对模型进行不等比缩放后,若直接使用模型矩阵转换法线,问题显而易见(图片引用一开始链接),转换后的法线不再垂直于表面:
为了求出正确的法线,我们用切线T与法线N垂直的思想,转换后的T’与N‘仍然应当垂直;
T可以写成模型表面上两点位置的差,我们知道顶点转换直接使用模型矩阵没有任何问题:
T=PV1-PV2;
M(PV1-PV2)=MT;
所以切线直接使用模型矩阵转换也没有任何问题;
我们设矩阵G是转换法线向量的正确矩阵。可得(.表示向量点乘,结果为标量,两向量垂直时点乘结果为0):
(GN).(MT)=0;
利用矩阵乘法 ,上式可写为(结果为1*1的矩阵,唯一的值即为向量点乘的标量值):
(GN).(MT)=
乘法的转置就是转置的乘法:
==0
此处作者自己理解:我们知道应该为0(即法线与切线点乘为0),所以
=I(I为单位矩阵);
=I
所以G=
即法线矩阵 为transpose(inverse(model));
inverse逆置,transpose转置。
在本节开始时,我们说过在某些情况下使用Modelview矩阵是可行的。只要Modelview的3×3左上角子矩阵是正交的。这是因为在正交矩阵中,转置与逆置是一样的。那么什么是正交矩阵?正交矩阵是一个所有列/行都是单位长度,并且相互垂直的矩阵。这意味着,当两个向量乘以这样的矩阵时,经过正交矩阵变换后,它们之间的角度与变换前是一样的。简单地说,这种变换保留了向量之间的角度关系,因此变换后的法线仍然与切线垂直!此外,它也保留了向量的长度。那么,我们什么时候才能确定M是正交的呢?当我们把几何操作限制在旋转和平移时,即在OpenGL应用程序中我们只使用glRotate和glTranslate而不使用glScale。这些操作保证了M是正交的。注意:glLookAt也会创建一个正交的矩阵!