Hey Guys, so we stumbled across following problem:
After compressing textures that are uploaded to our site, we sometimes end up with files that arent exactly square (e.g. 640x639). When using loadFromUrl those files wont work correctly and wont show up at runtime.
here’s an example project: https://playcanvas.com/project/847274/overview/nonpotproblem
Press any button except “P” and it tries to load the non POT texture (639x640).
Pressing “P” will load the same texture but POT (640x640).
Testing with a basis converter we get correct files either way, but PlayCanvas seems to choke on the non POT one.
Any idea how to fix or work around this issue?
There would be no problem to change things in the engine, we just dont know where.
It looks like your basis converter is having trouble with the non-square image file and is unable to generate mipmaps from the file. Ideally, any texture that get uploaded would be manually resized to POT and square if possible. Even if it gets stretched or squashed, once it is used on an object that would have the correct shape, the texture should still appear correctly as it’s stretched and squashed back to the right dimensions
I’m a little confused. I see that the files are being pulled from the cloud. Presumably you used your own compression tool to crate the basis files that are uploaded there? Or were they uploaded to Playcanvas first, compressed, then put into storage on the cloud?
You say it works when using a different compression tool. If it works on the Playcanvas engine when using a different compression tool, I would be hard pressed to think that it was a Playcanvas problem rather than a compression tool problem. Could you elaborate a little more on what steps exactly you are taking when running into this?
The textures in question are not multiple of 4 in size and according to Compressed texture formats - Web APIs | MDN, DXT compressed images (WEBGL_compressed_texture_s3tc) must be a multiple of 4.
Since basisu creates compressed images that may be transcoded to multiple runtime compression formats (as well uncompressed) it doesn’t apply any restrictions at compress time.
This means you may end up at runtime with a compressed texture that just doesn’t work on the target.
This is already an issue for PVR textures. PVR textures must be POT and under WebGL 1 must also be square. We handle this at runtime here by transcoding to an uncompressed texture format if the texture has invalid dimensions.
The upside of this approach is that non-POT textures continue to work on devices that only support PVR (the engine prefers almost all other runtime formats over PVR). The downside being increased memory usage at runtime in the case of PVR.
We have two options to fix this situation:
at runtime, transcode basis file to uncompressed format when texture isn’t multiple of 4
silently resize the input texture to multiple of 4 before compressing it on the PC backend