In the vertex shader we usually create TBN matrix:
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * Tangent.xyz);
vec3 b = normalize(gl_NormalMatrix * Bitangent.xyz);
mat3 tbn = mat3(t, b, n);
This matrix transform vertices from Tangent space into Eye/Camera space.
Now for normal mapping (done in forward rendering) we have two options:
- inverse tbn matrix and transform
light_vector
andview_direction
and send those vectors to the fragment shader. After that those vectors are in Tangent space.- that way in the fragment shader we only need to read normal from a normal map. Since such normals are in Tangent space (by "definition") they match with out transformed
light_vector
andview_direction
. - this way we do light calculations in Tangent space.
- that way in the fragment shader we only need to read normal from a normal map. Since such normals are in Tangent space (by "definition") they match with out transformed
- pass the
tbn
matrix into fragment shader and then transform each normal read from a normal map by that. That way we transform such normal into View space.- this way we do light calculations in Eye/Camera space
Option 1 seems to be faster: we have most transformations in the vertex shader, only one read from normal map.
Option 2 requires to transform each normal from normal map by the TBN matrix. But it seems a bit simpler.
Questions:
Which option is better?
Is there any performance loss? (maybe texture read will "cover" costs of doing the matrix transformation)
Which option is more often used?