mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.3k stars 35.35k forks source link

KTX2Loader may skip alpha when transcoding to ETC1 #22899

Closed donmccurdy closed 2 years ago

donmccurdy commented 2 years ago

Mentioned in the forums (Basis textures with alpha appearing fully black and white on some iPads...), KTX2Loader may select ETC1 as the transcoding target for textures containing alpha, meaning that the alpha channel is skipped. KTX2Loader selects a transcode target based on the weights defined here:

https://github.com/mrdoob/three.js/blob/244c8f1cdae7feffd1c577446b45161849a057ee/examples/jsm/loaders/KTX2Loader.js#L475-L482

On macOS, this example looks fine in Chrome and Firefox for me, but not in Safari: https://threejs.org/examples/?q=ktx2#webgl_loader_texture_ktx2

Screen Shot 2021-11-27 at 9 55 55 AM

The dark upper right corner shows that alpha is lost. Notably, when transcoding an ETC1S texture, priority of ETC1 is higher than priority of DXT. That would make sense if the texture didn't have alpha, but not if it did — you need ETC2 for alpha.

There's an 'easy' fix for this – we could just skip ETC1 and go to the next highest priority target format for textures with alpha. But, I was under the impression that iOS and macOS devices should support more formats than this. I'm using an M1 chip, which should support practically every GPU texture format under the sun (Khronos WebGL Guidelines, April 2021). As of June, Safari was running WebGL on Metal via ANGLE. It seems really unfortunate that we can't get ETC2 or ASTC support on the latest Apple devices, and I thought that was on the roadmap. Anyone know if I've missed something there?

hayden2114 commented 2 years ago

Thanks for filing this Don. I'm copying over the temporary solutions from the forum for convenience.

ktx2Loader.detectSupport( renderer );
ktx2Loader.basisLoader.workerConfig.etc1Supported = false;

OR you can add if ( opt.if === 'etc1Supported' && hasAlpha ) continue; to getTranscoderFormat() in the KTX2Loader or BasisTextureLoader (depending upon the three version you're using) where the continue statements are

donmccurdy commented 2 years ago

Background on WebGL / ANGLE / Safari: https://github.com/KhronosGroup/3D-Formats-Guidelines/issues/17

tomthebearded commented 2 years ago

Thanks for filing this Don. I'm copying over the temporary solutions from the forum for convenience.

ktx2Loader.detectSupport( renderer );
ktx2Loader.basisLoader.workerConfig.etc1Supported = false;

OR you can add if ( opt.if === 'etc1Supported' && hasAlpha ) continue; to getTranscoderFormat() where the continue statements are

Hi, i've tried this but without success.

donmccurdy commented 2 years ago

@tomthebearded there are some more details in the forum thread that might help, especially printing the list of formats your device does support. If that's not working for you, could you follow up with more details on the forum thread?

donmccurdy commented 2 years ago

WebKit bug / feature request: https://bugs.webkit.org/show_bug.cgi?id=233817

tomthebearded commented 2 years ago

@tomthebearded there are some more details in the forum thread that might help, especially printing the list of formats your device does support. If that's not working for you, could you follow up with more details on the forum thread?

Thank you

donmccurdy commented 2 years ago