Ktx2 texture flipped vertically on iOS


we recently started converting our textures to ktx2 and realized that they are flipped on iOS, while they look fine on a desktop PC.

It is exactly the same problem as described here:

…just that we run on iOS 17, so I assume it is not related.

I wonder if we are making a mistake with converting the texture. An example can be found in this playground:

This is a sample texture:
test.ktx2.zip (2.3 KB)

This is the source file:

We are using this command:

toktx --encode uastc --zcmp --target_type RGBA test.ktx2 test.png

Are we forgetting something while converting the image?

Kind regards

cc @ryantrem

1 Like

I didn’t get a chance to look at this much today, but I should be able to take a look tomorrow or Friday!


I tried this Playground out a bit myself and what I observed is:

  1. Texture appears flipped on iPhone
  2. Texture appears flipped on Windows
  3. Texture appears not flipped on Mac

From this existing issue, it seems like the expectation is that flipping a texture (e.g. invertY) will never work for compressed textures, but it seems like it does specifically for Mac.

@zacherl when you say "they are flipped on iOS, while they look fine on a desktop PC, " are you saying the behavior is different between iOS and Windows for you?

1 Like

Sorry, I think I was not clear. I tested on an iPad and on a MacBook in Chrome, not on Windows - I can do that on Tuesday.

What I found strange is that in the existing issue you linked, the playground example works on iOS and on Chrome on a MacBook. I also tried the command in that post to generate the compressed texture:

toktx --genmipmap --bcmp --clevel 5 target.ktx2 source.png

…and strangely enough, the file generated by that command did not seem to have the same problem. However, --bcmp is deprecated and should not be used anymore, but as soon as I use the suggested replacement (–encode etc1s), it breaks again.

After chatting with @bghgary, I think the existing issue does actually capture the whole problem. Depending on your browser (e.g. Safari on iOS vs. Chrome on Mac, etc.), the compressed texture may be decoded into an uncompressed texture. If it is decoded into an uncompressed texture, then the invertY argument will have an effect. If it is decoded into a compressed texture, then it may have an effect (ktx1 for example) as it tries to use the texture transform to do the flip (relying on the shader to for the texture transform).

For your ktx2 case, if you open the inspector in Playground and select your texture, you can see the format and whether it is compressed. For example:

Edge on MacOS:

Safari on MacOS:

Safari on iOS:

My expectation is that the behavior is consistent depending on whether texture is compressed or not. If that is not what you are seeing, let me know on which platforms you are not seeing that and with which Playground and also please include a screenshot of the inspector for the texture.

Assuming you are seeing the “expected” behavior, the biggest problem right now is that it is not possible to ensure you have consistent behavior across all platforms/browsers for a compressed texture. I think the only workaround currently is to not use compressed, either by not compressing the texture at authoring time, or by not using a compressed texutre at runtime by setting KhronosTextureContainer2.DefaultDecoderOptions.forceRGBA = true.

I think a real solution is going to be what @bghgary described in the GitHub issue (probably consistently and correctly accounting for invertY in the texture transform and relying on the shader to flip compressed textures).


Thanks a lot for the clarification! I guess we could use uncompressed textures (we did that so far). However, another thought - what about setting invertY to false? This seems to let both Safari and other browsers behave the same. Am I missing something here, does it have another drawback?


1 Like

If you only need to use a given texture in one vertical orientation (e.g. you don’t need invertY false sometimes and true other times), then I believe always setting invertY to false and authoring the textures with the “correct” vertical orientation would also work. :+1:t2:


Thank you all for your input!