Open zeux opened 2 hours ago
For completeness also adding ORM and normal map for one material from the same asset (normal map encoded with -normal_map
flag); the conclusion here is the same as above.
Texture | ETC2 PSNR | ASTC PSNR | BC1 PSNR | BC7 PSNR |
---|---|---|---|---|
FlightHelmet_Materials_MetalPartsMat_OcclusionRoughMetal.png | 24.8572 | 24.8601 | 24.8328 | 24.8602 |
FlightHelmet_Materials_MetalPartsMat_Normal.png | 32.8355 | 32.8311 | 32.7714 | 32.8121 |
Please do not confuse dual-slice as RGB + A and dual-slice as Red-Green. BC5 is applicable only to the latter case. The former is handled with either BC7 or BC1/BC3.
The observed transcoding quality difference between BC1 and BC7 is a bit unexpected. I'll take a look.
@lexaknyazev BC5 was a typo and I meant BC3 (aka DXT5) above. Edited to correct this.
The guidelines for ETC1S format suggest that the applications should decode to BC7 (if available) with a fallback to BC1 (single-slice) and BC3 (dual-slice).
I'm curious, where does this recommendation come from? Intuitively, this seemed wrong to me because ETC1S is a comparatively weak format, and BC1 is usually able to match or slightly surpass its color encoding quality. Encoding a single-slice image into BC7 results in 8 bits per pixel; encoding into BC1 results in 4 bits per pixel (same as ETC1/2), which is more memory friendly.
I tried to gather a little bit of data to help validate this intuition; this is somewhat cumbersome since basisu no longer supports "-bench" command, but you can do this by encoding the texture into .basis file (basisu -basis file.png), unpacking it back (basisu -unpack file.basis), and using ImageMagick
compare -metric psnr
on the original .png and every unpacked image. I looked at the various diffuse textures for FlightHelmet asset (https://github.com/KhronosGroup/glTF-Sample-Assets/tree/main/Models/FlightHelmet/) and produced the following results:BC7 here is actually almost always slightly worse than BC1, with the exception of LeatherPartsMat; regardless a 0.04 delta in PSNR should never be worth doubling the texture memory.
(I'm not really claiming that FlightHelmet base color textures are representative, but I'm not sure if there's more complete data that motivated the recommendation and what that data is)
For dual-slice source images, BC3 and BC7 have the same memory footprint, so in that case I don't have a problem with the current guidelines as I assume the quality delta will be minimal and the size delta is non-existent.
cc @donmccurdy as this came out of a discussion on three.js PR; three.js currently follows the guidelines and as such uses BC7 for decoding on desktop when that is supported. This results in 2x memory consumption for single-slice textures vs what is optimal, which affects memory consumption and the time to upload the compressed assets to GPU. I haven't measured the transcode time and assume it's close, but maybe that's not the case?