Basis loader doesn't correctly load alpha channel texture on Android

I’ve found an issue where basis textures with alpha channels work fine on desktop but fail to load the alpha channel on Android.

I’m assuming the problem is it’s converting to a format like ETC1 that doesn’t support an alpha channel.

If the texture has an alpha channel it should fall back to an uncompressed texture rather than a format that doesn’t support alpha channels.

Playground test -

Screenshot on Android -

Pinging @bghgary

I think you are right when it comes to ETC1. It does not support alpha. I did the first implementation of KTX textures for BJS, KTX1 I think it is called now. I did a fall back in the case where the ETC1 got chosen as the format and the original texture was a PNG.

Fortunately, at least for current Android systems intended for graphics, think Occulus Quest, they are now being built with ASTC support. Old or just cheap phones are still going to have this problem.

Right, ETC1 doesn’t support alpha. To do this properly with Android, it will have to be decoded into two separate textures (one for RGB and one for A). I don’t think our Basis code deals with this.

That is one way to handle it. Do you want to try to fix this in the code and open a PR?

I don’t know your scenario, but you can try using KTX v2 instead of Basis. That’s the officially supported way as it is a ratified standard from Khronos. The support for KTX v2 is done in our code, but it hasn’t gone through much testing. The same can be said for Basis though.

My phone supports ASTC as confirmed by the babylonjs compressed texture test, however I don’t think Basis supports transcoding to ASTC yet does it? That would also still leave the problem with older devices.

My current workaround is to use PNGs for any texture that requires an alpha channel. I did think of storing the alpha channel as a separate black and white texture but (as per my other post) opacityTexture doesn’t support alpha test mode, which I require. I might get a chance to look at the Basis code myself at some point, do you know if it supports falling back to transcoding to uncompressed currently?

Edit: Actually there is a workaround for my original idea of storing the alpha channel separately so I will go with that for now.

Back in '17, I was way ahead, but now was just waiting for V2 from Gary. From the posts I saw, I thought this basis thing was V2. I did not actually look up what V2 was.

Hearing the word transcoding mentioned, I now kind of realize why ASTC is not supported with that ‘basis’ process. When I run the batch process I made to encode files using the PVRTex tTool, the ASTC part ran really long. I do not want to run something like that every time.

I would test out V2, but the Quest 2 I ordered will not get delivered until 10/13, and that is not the first thing I want to get to run. Actually will probably just stay in the box for a while, at that. Could debug with DXT on a desktop, but up to my eyes in problems.

This is a bit confusing, so I’ll try to clear it up.

There are two container formats. One is .basis from Binomial (the company that created the Basis Universal compression) and is not backed by any standards committee. One is .ktx2 backed by the Khronos Group. You can find out more about KTX v2 here:

The compression tech is called Basis Universal. It originally only supported ETC1S but now it also supports UASTC, both are universal formats that allow transcoding to GPU formats depend on the target platform.

The .basis support in Babylon.js was added because people requested it. I think we can update the bits to support UASTC, but I don’t think anyone has looked into it.

The .ktx2 support in Babylon.js was updated (thanks to @Evgeni_Popov) to use newer universal texture transcoders from Khronos which has much better performance and download size, currently only for UASTC. It currently still has a fallback path to the code from Binomial, but that will likely change once the universal texture transcoders is more flushed out.

Long story short, I would recommend using .ktx2 instead of .basis as it will become the standard. The implementation is not 100% yet though, so use cautiously.

1 Like