glTF-Transform icon indicating copy to clipboard operation
glTF-Transform copied to clipboard

Embed custom mipmaps in KTX2 roughness textures

Open donmccurdy opened this issue 2 years ago • 2 comments

In prior versions of three.js, THREE.RoughnessMipmapper did the following:

[RoughnessMipmapper] generates custom mipmaps for a roughness map by encoding the lost variation in the normal map mip levels as increased roughness in the corresponding roughness mip levels. This helps with rendering accuracy for MeshStandardMaterial, and also helps with anti-aliasing when using PMREM. If the normal map is larger than the roughness map, the roughness map will be enlarged to match the dimensions of the normal map.

This feature had to be removed (see https://github.com/mrdoob/three.js/pull/23143) as a runtime-generation option. However, because glTF-Transform already embeds mipmaps when converting textures to KTX2, it would make sense to (optionally) compute the same custom mipmaps for a roughness map and store them in the KTX2 container. Doing this offline gives the same rendering benefits, with no parsing or performance cost.

donmccurdy avatar Jan 04 '22 18:01 donmccurdy

@elalish I see RoughnessMipmapper.js depended on constants (r0, r1, ...) defined in the cube_uv_reflection_fragment fragment, and that those constants need to match PMREMGenerator. Do you know if this means roughness mipmaps generated by this method should only be used in three.js? Or would they still probably be better than the default mipmaps in other engines?


I believe the required tasks for this feature will be:

  • [ ] Parse original roughness and normal textures with ndarray-pixels
  • [ ] Compute default mipmaps for R, B, and A channels in roughness texture (if present) with ndarray-lanczos
  • [ ] Compute custom roughness mipmaps for channel G
    • ...based on RoughnessMipmapper.js implementation (https://github.com/mrdoob/three.js/pull/23143)
  • [ ] Write each mipmap to a lossless PNG file
  • [ ] Encode to KTX2 using KTX-Software
    • ...or @squoosh/lib pending https://github.com/GoogleChromeLabs/squoosh/pull/1017

donmccurdy avatar Mar 13 '22 17:03 donmccurdy

No, I just reused those constants for convenience. The roughness lost per normal map mip level is universal and independent of the style of PMREM.

elalish avatar Mar 14 '22 00:03 elalish