Normals retaining unit length after mip processing / up or down sizing


When handling formats intended for normal maps (BC5U), does Texture Tools ensure that the resulting texel values, assuming standard reconstruction, will always be normalized (modulo quantization error)?

Also, a “normalization” effect would be helpful to ensure the values going into other effects / mip map filters are normalized. We sometimes deal with scanned data that benefit from normalization at some point in the chain, and it would be nice to leverage the GPU capabilities in Texture Tools.


Hi @jesse.r.meyer! The short answer is yes; some additional details below.

  • The Texture Tools Exporter does something a bit more sophisticated when converting height maps to normal maps – internally, it stores and mipmaps slope-space textures, then converts them to normals! This gives a somewhat more accurate result than mipmapping normals, and is based on the approach used in LEAN mapping. The idea is that mipmapping a normal map should be the same as mipmapping a height map, then converting each mip to a normal map. Slope-space textures satisfy this, while normal maps don’t.
    • If you uncheck Normal Map Settings > Normalize, you’ll get raw slope-space normals – (0.5 - 0.5 * dh/dx, 0.5 -0.5*dy/dx, 1). This isn’t very useful, though, since the x and y components can go outside of [0,1], and not many engines accept this format, so it might be changed in the future.
    • There is also a drawback to having the normals always be normalized: if they were mipmapped without renormalization, engines could use Toksvig mapping (Specular Showdown in the Wild West) to obtain an estimate of how much roughness to add to surfaces when viewed from a distance.
  • In the core NVTT library, there are more options for converting textures to and from common normal formats – see nvtt::Surface::transformNormals() and nvtt::Surface::reconstructNormals()! There’s also a slope-space demo in the NVTT samples here.
  • For two-channel formats like BC5S and BC5U, there’s usually no way to store a normal that isn’t normalized – the reconstruction algorithms can only reconstruct normalized normals. Three-channel formats like BC7 and the various BC3n formats can store unnormalized normals, though.
  • I’ve been thinking about a normalization effect, or something more general than that, for a while! Stay tuned for updates.

Hope this helps!

1 Like