我正在研究一些着色器,我需要转换法线。
我在一些教程中读到转换法线的方式是将它们与模型视图矩阵的逆矩阵的转置相乘。但我找不到解释为什么会这样,背后的逻辑是什么?
它源自法线的定义。
假设您有法线
N
和向量 V
,即与法线位于对象上相同位置的切向量。那么根据定义N·V = 0
。
切向量与物体表面的方向相同。因此,如果您的表面是平面,那么切线就是物体上两个可识别点之间的差值。因此,如果
V = Q - R
其中 Q
和 R
是表面上的点,那么如果通过 B
变换对象:
V' = BQ - BR
= B(Q - R)
= BV
通过考虑限制,相同的逻辑适用于非平面表面。
在这种情况下,假设您打算通过矩阵
B
来转换模型。因此 B
将应用于几何体。然后要弄清楚如何处理法线,您需要求解矩阵,A
,以便:
(AN)·(BV) = 0
将其转变为行与列的关系,以消除显式点积:
[tranpose(AN)](BV) = 0
将转置拉到外面,去掉括号:
transpose(N)*transpose(A)*B*V = 0
所以这就是“法线的转置”[与]“已知变换矩阵的转置”[与]“我们正在求解的变换”[与]“模型表面上的向量” = 0
但是我们首先声明
transpose(N)*V = 0
,因为这与说N·V = 0
是一样的。因此,为了满足我们的约束,我们需要表达式的中间部分 - transpose(A)*B
- 消失。
因此我们可以得出结论:
transpose(A)*B = identity
=> transpose(A) = identity*inverse(B)
=> transpose(A) = inverse(B)
=> A = transpose(inverse(B))
我最喜欢的证明如下,其中 N 是法线,V 是切向量。由于它们是垂直的,因此它们的点积为零。 M 是任何 3x3 可逆变换 (M-1 * M = I)。 N'和V'是M变换后的向量。
为了获得一些直觉,请考虑下面的剪切变换。
请注意,这不适用于切向量。
transpose(N)*V = 0; //OK
transpose(N)*invert(M)*M*V = 0; //OK
(transpose(N)*invert(M))*(M*V) = 0; //OK
(transpose(N)*invert(M))*S' = 0; //(1) OK
transpose(N')*S' = 0; //(2) OK
transpose(N') = transpose(N)*invert(M); **// Why??? Not OK**