根据OpenGL红皮书附录F,一个规则的三维变换矩阵M可以用来计算法向量上的作用,如:
normalTransformed = transpose(inverse(M)) * normal
然而,虽然与变换后的法线相关联的正交平面确实与变换后的曲面平行,但可能发生的情况是,变换后的法向量本身正指向与我预期相反的方向,即“进入”曲面,而不是“离开”曲面。
如果我想让normalTransformed指向正确的方向(也就是说,当它所连接的表面未被转换时,它所指向的方向相同),那么我应该如何从数学上做到这一点呢?
示例
假设我的曲面法线是(0,0,1),而我的变换是Z方向上10的平移。然后,变换矩阵M是:
1 0 0 0
0 1 0 0
0 0 1 10
0 0 0 1
转座子(反向(M))则是:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 -10 1
适用于齐次坐标下的曲面法线(0,0,1),即(0,0,1,1),这给出:
normalTransformed = (0,0,1,-9)
从齐次坐标返回:
(0,0,-1/9)
正规化至长度1:
(0,0,-1)
它指向与原始法向量(0,0,1)相反的方向。
发布于 2012-05-15 01:23:32
应用于齐次坐标下的曲面法线(0,0,1),即(0,0,1,1)
好了,停在那儿。
如果你要把曲面法线看作齐次坐标,你用一个零作为W分量,而不是1。现在,你可能很快就会意识到你不能除以零,但这也是为什么你不对法线做齐次的数学。
正常不是一个位置,而是一个方向。方向没有位置,所以翻译它们是没有意义的。具有W=0的同构位置表示一个无限远的“位置”(这就是为什么您不能将它们分开)。无限远的位置与每一个有限的点都是无限远的。
因此,在无穷远处的位置就是一个方向:它不会改变方向,不管你从什么(有限)位置看它。
现在,如果您有一个4x4矩阵,并且需要通过它来转换一个法线,那么您只需要使用W=0,因为它可以解决数学问题。它去掉了矩阵的翻译成分。后变换W分量应完全忽略。
因此,在转换之后,您可以得到以下内容:
normalTransformed = (0,0,1,-9)
在忽略W组件之后,它变成:
normalTransformed = (0,0,1)
更有可能的是,你的正常人实际上并没有在正确的方向上开始。当然,在没有代码和数据的情况下,可以说的不多了,但假设输入是合法的,那么数学就可以工作。
另外,不要在着色器中做反/转置。在CPU上执行,并将生成的矩阵传递给着色器。
发布于 2012-05-15 15:17:59
问题是,您被w
坐标除以,就好像您的正常值是一个点一样。(当使用w<0
时,这种划分将逆转您的正常情况。)相反,您需要完全忽略w
-coordinate:完全放弃它,而不是按照它进行除法。
你的法线不是一个点,它在技术上是一个协向量(这就是为什么它与点和向量不同的原因)。它实际上没有一个w
-coordinate --添加它的唯一原因是为了方便使用现有的4x4矩阵例程。
如果确实添加了任意的w
-coordinate,则具有给定法线的平面的齐次坐标。像法线一样,这样的平面也是由变换点的矩阵的逆转置来转换的(注意,用它的w
-coordinate除以平面也是没有意义的--平面也不是点!)
如果法线是从三角形派生出来的,则三角形的平面应该具有这个法线--然而,法线显式缺乏确定该平面是哪个平面的w
-coordinate。将任意的w
添加到法线(无论是0
、1
还是其他什么)意味着选择带有该法线的任意平面,因此转换它将产生一个与转换的法线相同的任意平面;这就是为什么在用4x4矩阵进行转换后,需要忽略w
。
发布于 2012-05-15 04:33:22
Nicol Bolas在他的回答中所写的是绝对正确的,事实上,我不会重复这些概念。
但我在问题中注意到,有几点可能是有趣的。
首先,正规矩阵通常被定义为模型视图矩阵左上角3x3矩阵的逆的转置。这是因为法线不是用齐次位置来定义的,实际上,4x4矩阵是不必要的;如果您想使用整个模型视图矩阵,请按照Nicol Bolas的方向,但数学不变。(因为w是零)。
第二,你说过
,我希望normalTransformed指向正确的方向(也就是当它所连接的表面未被转换时所指向的相同方向),我应该如何从数学上做到这一点?
利用正态矩阵与模型变换进行相干变换(实际上,法矩阵是由模型视图矩阵导出的)。我可以从你的话中了解到,你想要的是正常而不是改变.实际上,你为什么要改变它?你可以直接使用“正常”。
https://stackoverflow.com/questions/10596548
复制相似问题