这篇文章的思想源于潘李亮的《3D变换中法向量变换矩阵的推导》一文。 其实也就是看了篇文章后才知道,原来法向量的变换矩阵与定点的变换矩阵是不一样的。而《DirectX 9.0 3D游戏开发编程基础》这本书的作者视乎也忽略了这点(此书的p306贴出的代码部分,是将顶点的变换矩阵直接用作法向量的变换矩阵)。正如《3D变换中法向量变换矩阵的推导》一文{zh1}所说的,“即使你看到了所谓的正确的结果,那也是近似正确的,至少在理论上,它就是不正确的^_^。” 为什么法向量不能利用顶点变换矩阵来进行变换呢?可以从一个例子中看出来: 三维平面: x + y = k 法线n =[1 1 0] |2 0 0 0 | 其中*表示矩阵相乘。 可以看出,变换后的法线不再与面垂直了。 那法向量的变换矩阵是什么呢?这个推导过程很简单。 下面的式子本是源自于《3D 变换中法向量变换矩阵的推导 》一文,为了方便表示,进行了一些改动:
Q1,Q2:P1、P2变换到视图坐标系中的点 N:是P1、P2所在平面的法向量 M:是视图空间中,N所对应的法向量 Mv:变换矩阵 世界坐标系中,P1、P2点组成的向量与法向量N垂直: (1) N*(P1-P2)'=0 其中,'表示转置,*表示矩阵乘。将向量相乘写成矩阵相乘的形式,而且这里是利用的矩阵左乘来进行坐标变换,要注意DirectX中是利用的矩阵右乘来进行坐标变换的,请注意区别。 式子(3)中:(Q1-Q2)'=Mv(P1-P2)'带入(2)式后:(4)M*Mv*(P1-P2)'=0。 比较(1)、(4)后得到:(5)N=M*Mv 注:这里我只能说比较(1)、(4)得到,因为从线性代数角度这两个式子推不出式子(5),我也希望大家能够给出更合理的说法和推导过程。 (5)N=M*Mv=>(6)M=N*IN(Mv)。其中IN(Mv)表示Mv的逆矩阵。 所以 (6)M=N*IN(Mv)=>(7)M'=( IN(Mv) )'*N'。 由式子(7)得到:法向量的变换矩阵为“顶点变换矩阵的逆矩阵的转置”。 从线性代数角度,“矩阵的逆矩阵的转置”与“矩阵的转置再求逆”是相等的,因此也可以说成:“顶点变换矩阵转置后的逆矩阵”。 恭喜你,读到这里,你已经掌握了法向量的变换矩阵的推导。也许你有点担心,DirectX中是利用矩阵右乘进行变换的,那么,到底法向量的变换矩阵是不是也一样呢?其实,你可以自己推导了。而且我刚刚用上面的方法粗略的推了下,结果应该是一样的。 |