In vertex shader, vertices are multiplied by MVP (projectionviewmodel) and passed to the fragment shader.
Why normals are only multiplied by modelview(view*model) instead of MVP?
Is it for proper lighting calculation?
In vertex shader, vertices are multiplied by MVP (projectionviewmodel) and passed to the fragment shader.
Why normals are only multiplied by modelview(view*model) instead of MVP?
Is it for proper lighting calculation?
[QUOTE=Lee_Jennifer_82;1281783]In vertex shader, vertices are multiplied by MVP (projectionviewmodel) and passed to the fragment shader.
Why normals are only multiplied by modelview(view*model) instead of MVP?
Is it for proper lighting calculation?[/QUOTE]
The lighting equations are invariant under affine transformation; rotating and/or translating the vertex positions, normals, light positions, and eye position by the same transformation should have no effect upon the result. This isn’t true if the transformation has a projective component. Consequently, neither the normals nor vertex positions used for e.g. specular lighting are transformed by the projection matrix.
In particular, if M is orthonormal, then dot(Ma,Mb) = dot(a,b) for any vectors a and b. Translation doesn’t affect direction vectors (with w=0) nor the difference between two vectors: If T is a translation matrix, Ta-Tb = a-b.
This is the main reason why the fixed-function pipeline has separate model-view and projection matrices, and why shaders normally maintain that distinction. The model-view matrix should never contain any projective component; that should only occur in the projection matrix.
And if the model-view matrix contains non-uniform scale or shear components, normals need to be transformed by the inverse-transpose of the model-view matrix. For an orthonormal matrix, the inverse is equal to the transpose, so the normal matrix and model-view matrix are identical. For the combination of an orthonormal matrix and a uniform scale, the inverse and transpose differ only by a scale factor, which isn’t relevant if the normals are explicitly normalised in the shader; in the fixed-function pipeline, this can be handed with glEnable(GL_NORMALIZE) or glEnable(GL_RESCALE_NORMAL).