Tangent Space Normal Maps

Tangent Space Normal Maps

Implementation Dependent

A common misunderstanding about tangent space normal maps is that this representation is somehow independent. Howerer, normals sampled/captured from a high resolution surface and then transformed into tangent space is more like an encoding. Thus to reverse the original captured field of normals the transformation used to decode would have to be the exact inverse of that which was used to encode.

This presents a problem since there is no implementation standard for tangent space generation. Every normal map baker uses a different implementation and, additionally, there is no standard for how the interpolated frame is to be used to transform the normal into tangent space.


To make matters worse it is not enough to use the same tangent space generation code. Most implementations have order-dependencies which can result in different tangent spaces depending on which order faces are given in or the order of vertices to a face. Others generate different results if the index list changes (multiple/single/single with duplicate vertices). And others again produce different results if degenerate primitives are removed.

Order-dependencies also result in mirrored meshes not always getting correct mirrored tangent spaces. See for instance an example of a commercial product used to produce tangent spaces, on a mirrored model, in figure 17a on page 45 in the master's thesis Simulation of Wrinkled Surfaces Revisited by Morten S.Mikkelsen.

There are additional examples of problems with different commercial products shown on pages 44, 52-56. These problems do not just occur with mirroring. The problem is general and is mostly visible at tangent space splits in locations where the vertex normal is shared among surrounding faces.

The Solution

The tangent space generation code of Morten S. Mikkelsen overcomes these problems. The implementation is designed, specifically, to make the generation of tangent space as resilient as possible to a 3D model being moved from one application to another. That is generate the same tangent spaces even if there is a change in index list(s), ordering of faces/vertices of a face, and/or the removal of degenerate primitives. Both triangles and quads are supported.

The implementation was made by Morten S. Mikkelsen during the development of his master's thesis and is free for anyone to use. It is contained in the two standalone files mikktspace.h and mikktspace.c This makes it easy for anyone to integrate the implementation into their own application and thus reproduce the same tangent spaces. This also makes the code a perfect candidate for and implementation standard. We hope the standard will be adopted by as many developers as possible.

The standard is used in Blender 2.57 and is also used by default in xNormal since version 3.17.5 in the form of a built-in tangent space plugin(binary and code).

Pixel Shader Transformation

還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.