gl_NormalMatrix [duplicate]

旧时模样 提交于 2019-12-04 19:27:34


I have found that "gl_NormalMatrix - 3x3 Matrix representing the inverse transpose model-view matrix". Why does the matrix for normals have to be the inverse transpose model-view matrix? Why can't I just use the model-view matrix for this purpose?


See here:

This section was inspired by the excellent book by Eric Lengyel “Mathematics for 3D Game Programming and Computer Graphics”.

Many computations are done in eye space. This has to do with the fact that lighting is commonly performed in this space, otherwise eye position dependent effects, such as specular lights would be harder to implement.

Hence we need a way to transform the normal into eye space...

why can’t we just do the same with a normal vector? A normal is a vector of 3 floats and the modelview matrix is 4×4. Secondly, since the normal is a vector, we only want to transform its orientation. The region of the modelview matrix that contains the orientation is the top left 3×3 submatrix. So why not multiply the normal by this submatrix...

Lets have a look at a potential problem...

In the above figure the modelview matrix was applied to all the vertices as well as to the normal and the result is clearly wrong: the normal is no longer perpendicular to the surface.

So now we know that we can’t apply the modelview in all cases to transform the normal vector. The question is then, what matrix should we apply?

Consider a 3×3 matrix G, and lets see how this matrix could be computed to properly transform the normal vectors...

the correct matrix to transform the normal is the transpose of the inverse of the M matrix. OpenGL computes this for us in the gl_NormalMatrix...


It is because the normal is a vector, which is a direction without a position... or at least a direction at any position. The top left 3 x 3 matrix of your normal 4 x 4 modelView matrix contains the rotation component of the modelView matrix. By applying the 3 x 3 you alter the direction of the normal vector. The 4th column of the ModelView matrix contains the translation component, and it makes no sense to be applying a change in position to a vector... a vector does not have a position. The 4 x 4 modelView matrix is required for points as these do have a position.


Well, Normals should not be affected by translation, so I would say that it has to do with putting the model-view matrix to the origin in order to use just the rotation and scaling aspects of the matrix to calculate the normals.