I’ve outlined the issue I’m encountering here, but thought it might be an issue on the three.js side of things instead of the basis texture so I’m posting here as well.
@Hayden
Hey dude, I think you need to change the min and mag filter type to THREE.linearFilter, the number code is 1006 if I remember, you can also set this in your .gltf code if you search in there for min filter you will find a min and mag value, one of those values is the right one that needs to be pasted into both min and mag filter…
Thanks for the quick responses guys @Lawrence3DPK@playbyan1453 . Actually, the texture’s min and mag filter were already set to code 1006, which is THREE.LinearFilter, by default.
Here’s the code that’s loading the basis texture and applying it. The mesh is imported with a MeshBasicMaterial who’s map is a 4x4 white png so I’m just switching out that image with the basis texture.
this.basisLoader.load(`/textures/scene/${node.material.userData.basisSrc}.basis`,
(texture) => {
texture.encoding = THREE.sRGBEncoding;
node.material.map = texture;
if (node.material.userData.basisSrc.includes('alpha')) {
texture.magFilter = texture.minFilter = THREE.LinearFilter; // just added this in reply to forerunrun but no success
node.material.transparent = true;
}
node.material.needsUpdate = true;
}
He brought up the same point I presented in my previous post:
The only thing that looks iffy is the texture format being used for PVRTC1:
iPad = THREE.RGB_PVRTC_4BPPV1_Format = 35840;
His suggestions to me:
For an alpha texture like this, it may be better to use 4444 or 32-bit instead of PVRTC1 (or perhaps a larger texture).
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.
Still no solution though. Anyone know how to leverage 4444 or 32-bit format? Or have any other ideas?
One other note that seems weird to me, which you’ll find in the thread on basis github:
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.
Now I’m thinking potential solutions could be updating three.js past v111 or implementing a KTX2Loader. Will report back if I do indeed test those solutions
I would suggest trying to use KTX2Loader to embed .ktx2 textures in the model, yeah. If that isn’t working I can look into it further, but putting .basis files in glTF models is not really officially supported and I don’t think I can investigate that. The Basis compression technology is the same either way, it’s just a different “container” format around that data.
@donmccurdy I’m going to attempt to fix this issue using ktx2 since the three.js example with ktx2 and alpha works on my iPad that is breaking with the regular basis texture with alpha.
A couple of questions for you though as I’m sorta confused about ktx2.
I’m using three.js v111 and would like to stay with this version for the time being since I’m at the end of this project’s dev cycle. Can I still use the KTX2Loader? I see v111 only has the KTXLoader. Can I add the KTX2 loader code into the npm package in three/examples/jsm and expect it to still work?
Download an installer for KTX-Software from the “Assets” dropdown here: Releases · KhronosGroup/KTX-Software · GitHub. This will install a toktx CLI tool that can convert PNG or JPEG images to .ktx2 files. Converting .basis to anything else would require some custom code.
Can I still use the KTX2Loader [in v111]? I see v111 only has the KTXLoader. Can I add the KTX2 loader code into the npm package in three/examples/jsm and expect it to still work?
@donmccurdy okay so I converted my png file to ktx2 using toktx but the file is 5x larger than the png file. What am I missing here?? Would it be better to just use the png?
aha, the --uastc or --zcmp options made the .ktx2 file about the same size as the png! Looking at your answer, I never knew that basis wouldn’t always result in smaller size - they’ve always given a reduction of anywhere from 50-90% reduction of my textures so I was surprised to see the file bigger.
Anyways, the solution I have settled on is falling back to png textures on the few devices where this black and white basis issue is occurring and that’ll have to suffice for now. If I get around to implementing ktx2 textures I’ll update this thread with the solution.
Again, thanks so much for your guidance. You’re the man.
Circling back around on this as a new but similar issue has come up.
I have ktx2 textures with alpha embedded in a glb and they work great on every device + browser I’ve tried except for Safari on MacOS. The alpha channel is ignored and the texture appears as black and white. It’s because the basis texture’s format becomes RGB_ETC1_Format on Safari + MacOS. To reiterate, safari on my iPhone works fine and Chrome and Firefox work fine on the same Mac I’m having the problem on, because the basis texture’s format becomes something with RGBA.
I wanted to make sure this wasn’t an issue with my project or potentially the toktx version I’m using so I went to the ktx2 example on threejs.org on safari and the transparency is showing up black there too.
Any ideas on solutions to this problem? My current plan is to check the format of the loaded compressed textures and if it doesn’t contain an alpha channel then I’ll load in a png version of the texture.
Hm, that’s interesting… Could you print the value of kxt2Loader.workerConfig after detectSupport() has been called, on your macOS device? This depends on more than just the browser and OS, but on my macOS device (M1 Pro), I get —
Currently the transcoder prefers ETC1 over DXT, but maybe that shouldn’t be the case for textures with alpha channels. This could be worth filing a bug for.
I’d also thought that Safari + ANGLE was supposed to support more texture formats on M1 devices, but I’m not seeing it at the moment.
My output is the same as yours on Chrome and Firefox as well.
Is the issue happening on your device on the ktx2 example on three.js?
In regards to the ETC1 being prioritized over DXT, that does seem like the problem for these transparent textures. Is there a way I could edit the transcoder to use DXT instead of ETC1?
I’d like to figure out what is happening with Safari’s support for ETC2 and other formats, but in the meantime we should probably patch this in KTX2Loader yeah.
Okay that worked! I followed your directions and set ktx2Loader.basisLoader.workerConfig.etc1Supported = false.
Now the texture format is RGBA_S3TC_DXT5_Format , which supports the transparency.
Do you think this patch is okay for production? Would be ideal if KTX2Loader would check if the texture has alpha and fallback to an RGBA format instead of RGB. Let me know if you’d like me to file an issue or something on three.js github.
I patched the basis/ktx2 loader by adding if ( opt.if === 'etc1Supported' && hasAlpha ) continue; to getTranscoderFormat() and then I don’t have to fiddle with the workerConfig. Let me know if you think is the best solution @donmccurdy