おたくのスタジオ

法向量变换

模型的顶点的法向量一开始是定义在模型坐标系中的,在将模型布置在场景中后,根据光照模型计算颜色时需要用到顶点法向量,由于光照都是在世界坐标系中进行计算,这时用到的法向量也应该是定义在世界坐标系中。所以我们需要设法将顶点法向量从模型坐标系中转换到世界坐标系中。

我们已经知道通过缩放、旋转、平移三种基本操作合成的模型-世界变换矩阵可以将模型顶点坐标从模型坐标系中转换到世界坐标系中。那么这个模型-世界变换矩阵是否也可以将顶点法向量转换到世界坐标系呢?如果不行,那么需要找到一个可以完成这个任务的矩阵。

模型变换矩阵是否可以用于转换法向量

normal-tran-a

normal-tran-b

如图所示:图中的线段AB经过了缩放变换。上图中点A = (0,1),B = (1,0),法向量N = (1,1);下图中经过y坐标值放大两倍的变换后,法向量N = (1,2),而向量T’ = A - B = (-1,2),法向量N’不再与线段AB垂直。

寻找用于变换法向量的通用矩阵

设法向量为$N$,三角形表面某一切向量为$t$,则有:
$$
N \cdot t^T = 0
$$
写成转置形式,是为了方便进行矩阵运算。设模型-世界变换矩阵为$M$,变换后的切向量为$t’$,法向量为$N’$,则有:
$$
\begin{align}
N’ \cdot t’^T &= 0 \\
N’ \cdot (t \cdot M)^T& = 0 \\
N’ \cdot M^T \cdot t^T &= 0
\end{align}
$$
可以得到
$$
N’ \cdot M^T = N
$$
所以变换法向量的矩阵为$(M^T)^{-1}$。

如果一个变换矩阵只包含旋转的话,它一定是个正交的矩阵,即:
$$
M^T = M
$$
而且,这时还有
$$
M^T = M^{-1}
$$
结合一下可知在一个只包含旋转的变换里。法向量的变换矩阵的确就是模型-世界变换矩阵。但是如果变换中包含非正交的因素,如:平移、不等比缩放、错切等。那情况就不一样。即使看到了所谓的正确的结果。那也是近似正确的,至少在理论上,它就是不正确的。

以不是三个坐标方向的等比例缩放为例,有一种可以简洁推算法向量变换矩阵的方法:

如果模型被不成比例的缩放,在不同方向上会有不同程度的拉伸或者压缩,顶点的坐标会因而伸缩。但是如果对法向量进行同样的伸缩,那么法向量将不再垂直于对应的表面顶点的法向量是该顶点所在几个表面法向量的平均值)。

此时要对法向量进行正确的变换,应该是对其进行相反的缩放(比如xy是1:2缩放,那么法向量xy就要2:1缩放。)所以法向量的变换矩阵中缩放矩阵应该是原来顶点变换缩放矩阵逆矩阵

这个怎么做到呢,如前所述,缩放矩阵并不是正交矩阵,不能通过转置来得到逆矩阵。直接对原来的world矩阵求逆的话,旋转的部分也同时被求逆了。但是旋转又要求用原来的旋转。但是旋转矩阵是正交矩阵,转置后即可得到逆矩阵。

于是可以采用这样的方法:对World矩阵求逆,这样就同时得到了旋转和缩放的逆,然后进行转置再将旋转矩阵变回来,因为缩放系数在对角线上所以不会有影响。这样得到的变换矩阵就可以用来正确变换法向量了。关于转置,可以变换矩阵和向量相乘的顺序,这样就相当于和转置矩阵相乘了。

所以要做的只是求出逆矩阵,然后变换矩阵和向量原来的相乘顺序。