Home › Forums › GAMES在线课程(现代计算机图形学入门)讨论区 › 作业3 bump mapping中TBN的t 公式怎么推导的
Tagged: 作业3,inverse transpose
- This topic has 11 replies, 8 voices, and was last updated 3 years, 3 months ago by LunaJohn.
-
AuthorPosts
-
-
vincentParticipant
Let n = normal = (x,y,z)
Vector t = (x*y/sqrt(x*x+z*z), sqrt(x*x+z*z), z*y/sqrt(x*x+z*z))其中normal是世界空间的法线吧?怎么直接计算出切线方向的呢?
-
这里说是计算切线,其实更准确一点是在找一条切线然后跟n和它俩的叉乘构成一个Orthonormal basis。
其实n定义了一个三维空间中的平面P,而P上的任意一条向量都与模型上的与法线n相对应的这一点相切。
代码里这个t,我感觉其实是找了一个挺巧妙的向量。
你可以这么想,n是由它在x-z平面上的投影和它的y-component构成的。你把这个投影旋转到与y轴重合,n的y-component就到了一个平行于x-z平面的平面上,那么它的x,z坐标,就是t的x,z坐标。然后很显然,t的y坐标就是n在x-z平面上的投影的模长。
不过,代码框架里的这段应该是有点问题的,n跟t并不垂直。解出来的t的x,z坐标应该是-x*y/sqrt(x*x+z*z),-z*y/sqrt(x*x+z*z)。或者x,z是对的,那y就要变成负的。总之是有点问题。
然后代码里选定了n为z轴,t为x轴,b为y轴(轴的选定满足了右手坐标系三轴的叉乘法则),所以才能看到TBN = [t b n]这段代码。这个TBN矩阵是用来把下面计算出来的perturbed normal从本地坐标系转化到世界坐标系的。然后我也有个问题想请教一下,rasterizer的代码里这段:
Eigen::Matrix4f inv_trans = (view * model).inverse().transpose();
应该是用来把模型的法线从模型空间转化到世界空间的,但是难道不是只要inverse就够了吗,为什么还要transpose一下?This post has received 2 votes up.-
vincentParticipant
非常感谢你的解释,至于你的问题,我也不清楚。
-
我刚才突然开窍了哈哈,你试一下让inv_trans = view * model,效果是一样的。原理简单说的话,是我们在变换模型的缩放、位置和旋转的时候,只有旋转会真的影响到法线,因为法线是方向向量,w是0。
解释清楚一点,就是我们想要view space里模型的法线在世界坐标中表示的方向。那模型经历了一系列的缩放、平移和旋转,而其中只有旋转会影响法线。当我们用view * model去乘法线的时候,法线就经历了与模型一样的旋转(缩放其实也会生效,但是反正要归一化所以无所谓),而平移是无效的。于是我们就有了法线在世界坐标中表示的方向。
那原代码中的inv_trans其实我觉得有点怪怪的,虽然效果一样。如果我们不考虑平移,(view * model).inverse()这个矩阵会对法线进行与模型相反的缩放效果和相反的旋转效果,而inv_trans会对法线进行与模型相反的缩放效果(缩放效果在对角线上所以转置不影响)和与模型相同的旋转效果(旋转矩阵的逆与转置相同),那么我们也就得到了和对法线施加view * model这个矩阵一样的有效效果。-
shadowlrParticipant
不是喔 非一致缩放也会影响到法线
-
-
-
Jamie GuanParticipant
谢谢你的推导!我这里画了一张图也许能够帮助更好地解释
This post has received 2 votes up.Attachments:
You must be logged in to view attached files. -
LunaJohnParticipant
把切线从模型空间转换到世界空间是不能直接用model矩阵转换的,只要model矩阵是各个分量不等拉伸的矩阵,变换之后原来的法线和原来的面就不会垂直了,这个你可以在2维空间画一下x*1,y*2的变换,还是很明显的。
要得到正确的变换,就是要保证前后顶点切线和法线点乘为零,即TA cross NA = 0,TB(变换后的切线)=M1*TA,M1就是变换矩阵。那么可以得到 (M1*TA)^ * G*NA = 0(前面取转置默认3*1转为1*3),G就是法线变换矩阵,那么可以得到TA^(MA^ * G)N=0,那么我们可以知道当G为MA的逆转置矩阵时等式成立。ps:因为有些库帮我们处理了一些细节,3*1 * 3*3的计算是可以被当作1*3 * 3*3的,所以把矩阵 * 向量(m * v) 转化成 向量 * 矩阵(v * m) 相当于对矩阵transpose(v^ * m^)。
-
-
关于inverse transpose的问题,可以参考博客:
https://blog.csdn.net/chenhittler/article/details/51348209This post has received 1 vote up.-
anyuanParticipant
知道了。
-
-
yxsxyParticipant
感谢大佬的解释
-
-
AuthorPosts
- You must be logged in to reply to this topic.