为什么使用模型视图矩阵的反转置转换法线?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么使用模型视图矩阵的反转置转换法线?相关的知识,希望对你有一定的参考价值。
我正在研究一些着色器,我需要改变法线。
我在几个教程中读到了变换法线的方法,你将它们与模型视图矩阵的逆的转置相乘。但我找不到为什么会这样解释,那背后的逻辑是什么?
看看这个教程:
https://paroj.github.io/gltut/Illumination/Tut09%20Normal%20Transformation.html
您可以想象,当球体表面伸展(因此球体沿着一个轴或类似物体缩放)时,该表面的法线将全部“弯曲”为彼此。事实证明,您需要反转应用于法线的比例来实现此目的。这与使用反向转置矩阵进行变换相同。上面的链接显示了如何从中导出逆转置矩阵。
另请注意,当刻度均匀时,您可以简单地将原始矩阵作为普通矩阵传递。想象一下,沿着所有轴均匀地缩放相同的球体,表面不会拉伸或弯曲,法线也不会。
它来自正常的定义。
假设您有正常的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是任何3×3可逆变换(M-1 * M = 1)。 N'和V'是由M.转换的向量。
为了获得一些直觉,请考虑下面的剪切变换。
请注意,这不适用于切线向量。
如果模型矩阵由平移,旋转和缩放组成,则无需进行逆移调来计算法线矩阵。简单地将法线除以平方尺度并乘以模型矩阵,我们就完成了。您可以将其扩展到任何具有垂直轴的矩阵,只需计算您正在使用的矩阵的每个轴的平方比例。
我在我的博客中写了详细信息:https://lxjk.github.io/2017/10/01/Stop-Using-Normal-Matrix.html
不明白为什么在与模型矩阵相乘之前不要将方向向量的第4个元素归零。无需反转或转置。将方向向量看作两点之间的差异。将两个点移动到模型的其余部分 - 它们仍然与模型处于相同的相对位置。获取两个点之间的差异以获得新方向,第四个元素取消为零。很便宜。
以上是关于为什么使用模型视图矩阵的反转置转换法线?的主要内容,如果未能解决你的问题,请参考以下文章