法线的变换方式不同于顶点的变换。
顶点变换采用:gl_ModelViewProjectionMatrix * gl_Vertex
法线变换采用:gl_NormalMatrix*gl_Normal
NormalMatrix是ModelView矩阵逆的转置,由于gl_ModelViewProjectionMatrix 考虑了旋转、缩放、平移等因素,因此gl_NormalMatrix也考虑了旋转、缩放、平移等因素。
一般情况下,法线向量不应当随着缩放变换的,因此需要做缩放修正,对于一致缩放情况只需要做归一化处理即可,对于不一致的缩放需要在各分量乘以缩放系数(对于放大而言,需要乘以放大倍数)。
osg中对此矩阵是这样计算的:
osg/State.cpp
void State::updateModelViewAndProjectionMatrixUniforms()
{
if (_modelViewProjectionMatrixUniform.valid()) _modelViewProjectionMatrixUniform->set((*_modelView) * (*_projection));
if (_normalMatrixUniform.valid())
{
Matrix mv(*_modelView);
mv.setTrans(0.0, 0.0, 0.0);
Matrix matrix;
matrix.invert(mv);
Matrix3 normalMatrix(matrix(0,0), matrix(1,0), matrix(2,0),
matrix(0,1), matrix(1,1), matrix(2,1),