[SOLVED] Problem Concerning Non-POT-Textures

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:

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.

Thanks you!

640 is not power of two dimensions

POT is dimensions of 8, 16 , 32, 64, 128, 256 etc

Then lets ignore POT for a while ^^’

Can you tell me why the square one works and the other doesnt?

If I had to guess based on the warnings Firefox is spitting out:

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

1 Like

Using another converter we can get both files to work though, so it should be PlayCanvas’ problem?

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?

Yeah sure!

so we’re using this tool:

to convert the uploaded files into .basis format and then we pull those files via PC.

Using this Tool we get the exact files back, while PlayCanvas’ basis converter seems to struggle with them

@slimbuck might be able to advise here.

Quick update here - I’ve asked privately for @jvAW to send me a working and not-working .basis file so I can investigate further.

1 Like

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

Submitted https://github.com/playcanvas/engine/pull/3731 to make odd-sized DXT textures work at runtime.

But beware: such textures are uncompressed at runtime.

1 Like