sky.ktx2 (3.0 MB)
Because the exr file is too large, I plan to convert it to ktx2 for loading. However, during testing, I found that on some machines in the Mac system, there is an abnormal display with a black background (loading resources normally on Windows). There are no errors or warnings, which makes me very confused. The following are the versions and devices:
three.js 170,
macos big sur 11.7.10 google chrome128.06612.138 (succeed)
macos ventura 13.6.6 google chrome 130.0.6723.92 (succeed)
macos monterey 12.6.3 google chrome 130.0.6723.92 (failure)
macos sonoma 14.4 google chrome 130.0.6723.92 (failure)
macOS Sequoia 15.0.1 google chrome 129.0.6668.59(failure)
ktx2Loader.load('./sky.ktx2', (envMap) => { envMap.mapping = EquirectangularReflectionMapping scene.background = envMap })
If you open three.js examples and select the “RGBA16 Linear (UASTC HDR)” option in the sample dropdown, do you see success/failure on the same devices? And, could you share the GPU details? Are they M1/M2/M3 devices, or using NVIDIA or AMD GPUs?
Support for Basis UASTC HDR is new in r170, it’s quite possible there is a bug on some devices.
Okay, I ran the three.js examples on these devices, and they all look like the images below with no errors or warnings in the console. I now have compatibility for using EXRLoader on Mac. Here are the versions and devices and GPUs:
macOS Big Sur 11.7.10 Google Chrome 128.0.6612.138 intel hd graphics 5000 (success)
macOS Ventura 13.6.6 Google Chrome 130.0.6723.92 apple m1 (success)
macOS Monterey 12.6 .3 Google Chrome 130 .0 .6723 .92 apple m1 (failure)
macOS Sonoma 14.4 Google Chrome 130 .0 .6723 .92 Apple M2 (failure)
macOS Sequoia15.0.1 Google Chrome 129 .0 .6668 .59 Apple M2 (failure)
Hm, what are you testing with EXRLoader that fails? Does the official EXRLoader example look correct on these devices?
For the KTX2 file you attached earlier, if I modify the official KTX2Loader example to use your file, the page looks like this on Sequoia 15.0.1, M1 Pro, recent Chromium-based browser —
The JavaScript console outputs…
format: RGBA_ASTC_4x4
type: HalfFloatType
colorSpace: srgb-linear
… which is reasonable for the device, others might show BPTC instead of ASTC.
The direction is a bit off, let me confirm the issue.
There is no problem with loading this material using KTX2Loader (for ktx2) and EXRLoader (for exr).
The problem arises when I assign the material loaded with KTX2Loader to scene.background,
Some devices display successfully on macOS, while others experience anomalies
I hope to get
(From window format: RGB_BPTC_UNSIGNED)
But in some macos appeared
(From macos format: RGBA_ASTC_4x4)
Does the problem occur only when using texture.mapping = THREE.EquirectangularReflectionMapping
, or also without it?
It is sounding like a bug may need to be filed on three.js, if you would like to open a ticket with as much detail as possible: the KTX2 file, the demo/code with which you are testing it, and the specs from at least one of the devices on which the demo doesn’t work.
Yes, tested. The problem is in the use of texture.mapping = THREE EquirectangularReflectionMapping occurs
The problem on Mac appears to be caused by the scene.backgroundBlurriness
which needs to be set to greater than 0. WebGPU also seems to have the same issue.
I did try this with my GLTF Viewer on M2 Mac Mini and by loading the sky.ktx2
file as a background (with viewer’s BGND
button) and enabling / disabling equirectangular mapping (with viewer’s Eq
button).
Maybe try it yourself with the Damaged Helmet model, where it is sufficient to just paste this link into the URL option of the viewer.
/cc
on this topic, what is the way now to convert the exr to ktx2 for enviroment maps?
i think we need to use KTX-Tools with ktx create?
The new feature in three.js r170 (and the scope of this bug) is related to Basis UASTC HDR textures. KTX Software (and ktx create
) hasn’t yet been updated to support Basis HDR textures, so you’d need to use the encoder from GitHub - BinomialLLC/basis_universal: Basis Universal GPU Texture Codec instead. Typical usage is…
basisu texture.exr
… though depending on the goals and quality needs you may want to change some of the other flags.
When doing this for environment maps there are different possible approaches. You could compress the source .exr and if the file size is smaller that’s already a win, but note that PMREM generation creates a decompressed version at runtime, so you’re not getting VRAM savings. To get the VRAM savings you’d need to do PMREM generation on the source .exr ahead of time, export with EXRExporter, then compress that image with basisu instead, assigning it directly to the environment map slot and not using PMREM generation at runtime. I haven’t tested this full workflow yet, there could be some things left to work out.
That BinomialLLC page has a link to Live Encoder/Transcoder WebGL Examples
which then includes another link for .ktx2 texture transcoding/encoding test
.
This last link allows entering a URL for the file (PNG or EXR or HDR) anyone might want to have encoded to KTX2. This way one could place texture files in the GitHub repository and use the RAW link, similar to:
https://raw.githubusercontent.com/YourUserName/Repository/Branch/TextureFolder/blah_blah_blah_2k.hdr
Not really sure of what the correct settings should be on the encoder page but the KTX2 output file looks a little bright to me.
The bottom of the encoder page will show the log once it has finished encoding and then you could use its Download Encoded .KTX2 File
button to save the output.
For those who might be interested, now you could also try my Image to 3D Mesh viewer / converter to export EXR and HDR textures to KTX2 format.
There are 4 possible export options KTX2e
, KTX2e_Y
, KTX2u
and KTX2u_Y
:
e
is for ETC1S (smaller file not as good of a quality)u
is for UASTC (larger file but better quality)Y
is to Y-flip texture
Not necessarily that I got this conversion correct but if you are to be happy with the quality of the output then good for you.