为什么使用模型视图矩阵的反转置转换法线?

时间:2012-11-30 22:59:09

标签: opengl glsl game-engine game-physics

我正在研究一些着色器,我需要转换法线。

我在几个教程中读到了变换法线的方法是你将它们与模型视图矩阵的逆转换相乘。但是我找不到解释为什么会这样,那背后的逻辑是什么?

5 个答案:

答案 0 :(得分:40)

它来自正常的定义。

假设你有正常的N和一个向量V,它是一个与正常对象相同位置的切向量。然后根据定义N·V = 0

切线向量的运行方向与对象的表面方向相同。因此,如果表面是平面的,则切线是对象上两个可识别点之间的差异。因此,如果V = Q - R其中QR是表面上的点,那么如果您将对象转换为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))

答案 1 :(得分:28)

我最喜欢的证明是在下面,其中N是法线,V是切线矢量。由于它们是垂直的,它们的点积为零。 M是任何3×3可逆转换(M -1 * M = I)。 N'和V'是由M转换的矢量。

enter image description here

为了获得一些直觉,请考虑下面的剪切变换。

enter image description here

请注意,适用于切线向量。

答案 2 :(得分:26)

看一下本教程:

https://paroj.github.io/gltut/Illumination/Tut09%20Normal%20Transformation.html

你可以想象,当球体表面伸展(因此球体沿着一个轴或类似的东西缩放)时,该表面的法线将全部“弯曲”到彼此。事实证明,您需要反转应用于法线的比例来实现此目的。这与使用反向转置矩阵进行转换相同。上面的链接显示了如何从中导出逆转置矩阵。

另请注意,当刻度均匀时,您可以简单地将原始矩阵作为普通矩阵传递。想象一下,沿着所有轴均匀缩放相同的球体,表面不会拉伸或弯曲,法线也不会。

答案 3 :(得分:1)

如果模型矩阵由平移,旋转和缩放组成,则无需进行逆移调来计算法线矩阵。简单地将法线除以平方尺度并乘以模型矩阵,我们就完成了。您可以将其扩展到任何具有垂直轴的矩阵,只需计算您正在使用的矩阵的每个轴的平方比例。

我在博客中写了详细信息:https://lxjk.github.io/2017/10/01/Stop-Using-Normal-Matrix.html

答案 4 :(得分:-2)

不要理解为什么在与模型矩阵相乘之前,你不会将方向向量的第4个元素归零。无需反转或转置。将方向向量看作两点之间的差异。将两个点移动到模型的其余部分 - 它们仍然与模型处于相同的相对位置。获取两个点之间的差异以获得新方向,第四个元素取消为零。很便宜。