【发布时间】:2013-03-10 16:07:24
【问题描述】:
我只是想确保我正确理解 TBN 矩阵计算
在我们通常使用的顶点着色器中:
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * Tangent.xyz);
vec3 b = normalize(gl_NormalMatrix * Bitangent.xyz);
mat3 tbn = mat3(t, b, n);
据我了解,tbn 矩阵将向量从切线空间转换为眼睛空间。实际上我们想要反向 - 将向量从眼睛空间转换到切线空间。因此我们需要反转tbn矩阵:
tbn = transpose(tbn); // transpose should be OK here for doing matrix inversion
注意: tbn - 应该只包含旋转,对于这种情况我们可以使用转置来反转矩阵。
我们可以转换我们的向量:
vec3 lightT = tbn * light_vector;
... = tbn * ...
在几个教程中,我发现作者使用了这样的源代码:
light.x = dot(light, t);
light.y = dot(light, b);
light.z = dot(light, n);
上述代码的作用与乘以transposed(tbn) 矩阵相同。
问题:
我们应该像我上面解释的那样使用转置的tbn 矩阵吗?或者也许我错过了什么?
注意通过该解决方案,我们在顶点着色器中将向量 (light_vector) 转换为 TBN,然后在片段着色器中我们只需从法线贴图获取法线。其他选择是创建 TBN 矩阵,将 TBN 空间转换为眼睛空间,然后在片段着色器中转换从法线贴图读取的每个法线。
【问题讨论】:
-
定义“正确”?你把你的法线和切线向量的叉积得到你的双切线向量。一般来说,这对于大多数表面不是正确的。它可能对你来说是正确的,但大多数纹理映射不使用完全正交的映射到表面。
-
对,我已经更新了问题。我也改变了双切线计算。