2
$\begingroup$

Looking at various assets (models / textures / scenes) available online, I have noticed a trend that conflicts with my assumptions. Many of the normal maps contain texels whose vector length deviates from unit length by a significant amount.

For example, this image from Wikimedia Commons (https://commons.wikimedia.org/wiki/File:Normal_map_example_-_Map.png) contains many vectors (hundreds) that are around 15%+ shorter than unit length, and it is hardly an outlier (in fact, it would seem to have been chosen as an exemplary basic example). In other cases, I have found normal maps where the z component is uniformly set to 1.0.

On the specification side of things, I note that GLTF 2.0 merely states (https://github.com/KhronosGroup/glTF/issues/993) that a shader implementation should renormalize after sampling, but that it is not required for the maps themselves to have vectors of unit length.

It seems to me that this poses an accuracy issue. Certainly if normals are sampled using bilinear filtering, the result will generally be shorter than the texels used to generate it, and thus renormalization will be necessary. However, if this is the argument as to why it is not necessary to store as unit length vectors, then it seems short-sighted to me.

When sampling with e.g. bilinear filtering, if the texels are not all of the same length, the resulting normal will be biased in direction towards the samples with greater length. Therefore, even if you renormalize after sampling, you will not be able to recover the accuracy lost by not starting with unit normals in the first place.

So I would like to know why such low priority is seemingly placed on generating normal map textures that contain only unit-length normals. Is it just because the loss in accuracy isn't deemed to be significant enough subjectively/perceptually, or is there something else completely here that I am missing?

$\endgroup$
4
$\begingroup$

Maps with z = 1.0 everywhere are likely partial derivative maps. This is a variant on normal maps that's become fairly widespread. There are a few reasons to prefer it, but probably the most important is it lets you store the map as just two channels (red and green), which allows using better quality BC5 compression, while being cheap to decode in the shader. The normals in such a map are of necessity not all unit length, and as you pointed out that will affect interpolation and blending slightly, but this is generally deemed an acceptable trade-off.

However, if it's purporting to be a traditional old-school normal map and it has pixels that are significantly off from unit length, that sounds odd and probably unintended. I'm not sure why that would have happened in the particular Wikimedia .png example you linked. However, non-unit-length normals could generally be introduced by doing filtering/blending/compositing operations on the image without renormalizing after (for example, if a normal map was rendered at a higher resolution and then downsampled using a standard image resampling algorithm). They could also be introduced by lossy compression.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.