BinomialLLC / basis_universal

Basis Universal GPU Texture Codec
Apache License 2.0
2.7k stars 263 forks source link

basis textures with alpha appearing fully black and white on some iPads and older mobile devices #197

Closed hayden2114 closed 3 years ago

hayden2114 commented 3 years ago

Basis textures have been lifesaving when it comes to the texture space leverage it provides in my three.js projects! They work great but I've just encountered an issue I've never seen before and since it's on mobile/tablet devices it's tough to debug.

Most of the textures used in this scene are basis and are working perfectly but the two textures (trees and 3D buttons) that have an alpha component for their shadows are showing up black and white in some cases.

Image from iOS

I've witnessed it on my older iPad air running iOS 12, a brand new iPad pro I believe was running iPadOS 14 (not sure, tested on it at a best buy and had to be quick), and another old school Android Galaxy phone. I tried it on a regular iPad that was a 2019 model I believe and the textures showed up correctly. This has occurred in safari, chrome, and firefox so I don't believe it's a browser issue. I converted the textures from png to basis using the basisu command line program. Applying them programmatically to the glb's map in three.js v111 via BasisTextureLoader and GLTFLoader.

If anyone has any insights on why this would be occurring or potential solutions to the problem, I'd appreciate it a lot. I've just started looking into ktx2 textures - maybe that's a solution?

kenrussell commented 3 years ago

Please file a bug with as small a test case as you can on bugs.webkit.org. This is probably a bug in WebKit's WebGL implementation rather than a bug in the Basis Universal transcoders, and might already be fixed with substantial work that's been done in WebKit recently, but maybe not yet shipped. cc @grorg

richgel999 commented 3 years ago

Can you upload the .basis file? I'll transcode it using the basisu command line tool, then view the PVRTC1 .KTX file in Imagination Tech's PVRTexTool. If PVRTexTool views the KTX file OK (and I suspect it will), this means the texture data is OK and the problem is likely somewhere else.

hayden2114 commented 3 years ago

@richgel999 Yes here it is. Thanks a LOT for the reply!

alpha_basis_textures.zip

hayden2114 commented 3 years ago

Just for reference, I've found out a bit more info of what's going on. In three.js the texture's format is set to the following on each device.

// LAPTOP = THREE.RGBA_S3TC_DXT5_Format = 33779;
// iPhone = THREE.RGBA_ASTC_4x4_Format = 37808;
// iPad = THREE.RGB_PVRTC_4BPPV1_Format  = 35840;

Since the RGB_PVRTC_4BPPV1_Format is resulting in issues I've tried changing the format to the other versions of PVRTC but no luck.

richgel999 commented 3 years ago

I ran basisu.exe on your tree .basis file (basisu J:\dev\alpha_basis_textures\trees_alpha.basis), then opened the PVRTC1 RGB, PVRTC1 RGBA, and ETC2 RGBA files in PVRTexTool 64-bit. As far as I can tell they look OK:

image

The only thing that looks iffy is the texture format being used for PVRTC1: iPad = THREE.RGB_PVRTC_4BPPV1_Format = 35840;

This doesn't have alpha, while the others do. If you only use the RGB channels, you just get a black and white tree (see the window on the bottom left, which is PVRTC1 RGB only).

richgel999 commented 3 years ago

Also, as a side note, PVRTC1 alpha is tough to encode well in real-time, so there are some edge artifacts (that you don't see with ETC2). For an alpha texture like this, it may be better to use 4444 or 32-bit instead of PVRTC1 (or perhaps a larger texture).

hayden2114 commented 3 years ago

@richgel999 hmm okay interesting. Ya I noticed that the iPad format was RGB, which would make sense as to why no alpha is appearing. The weird part is it appears to be rendering the alpha channel of the texture instead of the RGB channels, since it's showing white on the tree, black on fully transparent ground, and grey on the shadow.

I really appreciate you digging into this. As for solutions, can you think of any?

hayden2114 commented 3 years ago

@richgel999 Just now seeing your suggestion "For an alpha texture like this, it may be better to use 4444 or 32-bit instead of PVRTC1 (or perhaps a larger texture)". How would I go about doing this? From my understanding, the device is deciding what format of texture is used? FYI I'm very new to basis textures

richgel999 commented 3 years ago

How would I go about doing this?

I'm not very experienced with three.js, so you may want to ask on one of their developer forums. The basis transcoder can supply 4444, 565, or 32-bit texture data (along with all the other GPU tex formats). But I'm unsure if three.js supports it.

Also, you may just want to see if the three.js folks have already fixed the problem, because it appears to be that they aren't using a RGBA format for PVRTC1.

hayden2114 commented 3 years ago

@richgel999 Gotcha.

I do have a question going on the forum here.

Three.js has a format RGBA_PVRTC_4BPPV1_Format but I tried that and it didn't fix the issue. For your reference, here's all the texture formats three.js supports https://threejs.org/docs/#api/en/constants/Textures.

Thanks again for your help and guidance!

richgel999 commented 3 years ago

As for solutions, can you think of any?

The PVRTC1 data being output by the transcoder (the .KTX file) looks correct in PVRTexTool, which is what we use as our "ground level truth", so I'm currently at a loss about what's happening. If you could change the shaders and visualize the channels separately, you could narrow down whether or not it's the texture data or something else.

hayden2114 commented 3 years ago

After your test and result of the .KTX file I'm thinking the issue is on the three.js side of things. I might need to update past v111 or try using the KTX2Loader in three.js (https://github.com/mrdoob/three.js/pull/18490).

kenrussell commented 3 years ago

Please note also that coming updates to WebKit's WebGL implementation on iOS will begin supporting ETC1/2 and ASTC compressed texture targets natively, so hopefully the PVRTC path should become less important over time. @grorg

hayden2114 commented 3 years ago

@kenrussell roger that, thanks for the update! Any clues on when that support will be introduced?

kenrussell commented 3 years ago

I'm not 100% sure. Please check webglreport.com on your iPads and see whether the extensions are actually already present - if you could provide a screenshot / saved version of that page from your devices that would help. If they aren't there then they must only be enabled on the betas, and the goal is to ship it later this year. @grorg

hayden2114 commented 3 years ago

@kenrussell Thanks for the info. Below are both screenshots from my iPad and iPhone. As you can see, iPad only supports PVRTC while iPhone supports PVRTC, ETC, and ASTC

Image from iOS Image from iOS (1)

sehurlburt commented 3 years ago

The detailed reporting is much appreciated! Even when it's not an issue in Basis Universal it's good for us to know about because being cross platform is critical, with your help we can then push the engines and platforms to add better support and let them know that we've done our low level piece for them.

hayden2114 commented 3 years ago

Of course! The work yall have done on Basis is incredible! My three.js projects would be no where near as good without it

grorg commented 3 years ago

What model iPad is this? And what version of iOS?

hayden2114 commented 3 years ago

iPad mini 3 running iOS 12.5

hayden2114 commented 3 years ago

I'm now trying to convert these two textures that have an alpha channel to .ktx2 type as it appears they work and are supported by three.js (https://threejs.org/examples/?q=ktx#webgl_loader_texture_ktx2). Am I able to use the basis command line tool to do this? I looked at the documentation and it only references ktx files. Anyone know what tool I could use to convert from basis or png to ktx2?

hayden2114 commented 3 years ago

@grorg it also happened on one of the brand new iPad Pro's I tried quickly at best buy. Not sure what it was running but I'd guess iOS 14 or iPadOS 14

hayden2114 commented 3 years ago

Don Mccurdy has helped me out with how to convert to .ktx2 textures https://discourse.threejs.org/t/basis-textures-with-alpha-appearing-fully-black-and-white-on-some-ipads-and-older-mobile-devices-when-rgb-pvrtc-4bppv1-format-is-used/22575/9