donmccurdy / glTF-Transform

glTF 2.0 SDK for JavaScript and TypeScript, on Web and Node.js.
https://gltf-transform.dev
MIT License
1.36k stars 147 forks source link

Embed custom mipmaps in KTX2 roughness textures #467

Open donmccurdy opened 2 years ago

donmccurdy commented 2 years ago

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 commented 2 years ago

@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:

elalish commented 2 years ago

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.