我只是想确保我正确理解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
矩阵将矢量从Tangent 空间转换为Eye 空间。实际上我们想要反向 - 将一个矢量从眼睛空间变换到切线空间。因此,我们需要反转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空间转换为眼睛空间,然后在片段着色器中转换每个从法线贴图读取的法线。
答案 0 :(得分:0)
顶点着色器中的TBN矩阵如下所示:
uniform mat4x4 tm_l2g_dir;
layout(location=3) in vec3 tan;
layout(location=4) in vec3 bin;
layout(location=5) in vec3 nor;
out smooth mat3 pixel_TBN;
void main()
{
vec4 p;
//...
p.xyz=tan.xyz; p.w=1.0; pixel_TBN[0]=normalize((tm_l2g_dir*p).xyz);
p.xyz=bin.xyz; p.w=1.0; pixel_TBN[1]=normalize((tm_l2g_dir*p).xyz);
p.xyz=nor.xyz; p.w=1.0; pixel_TBN[2]=normalize((tm_l2g_dir*p).xyz);
//...
}
其中:
nor - 是从实际Vertex位置到法线的法线向量(可以计算为来自此顶点的两个顶点的向量乘法)
tan,bin是垂直向量,通常与纹理映射轴或模型的teselation平行。如果选择错误的tan / bin向量,有时会出现一些光照伪影。例如,如果你有圆柱体而不是圆柱体是它的旋转轴,并且棕褐色是沿圆形垂直(切线)
tan,bin,也不应该彼此垂直
你可以自动计算TBN,但这会导致一些伪影。要做到这一点,你只需选择棕褐色矢量一个用于正常计算的顶点和bin = nor x bin
片段着色器中的我使用带有法线贴图的pixel_TBN来计算片段
的真实法线//------------------------------------------------------------------
#version 420 core
//------------------------------------------------------------------
in smooth vec2 pixel_txr;
in smooth mat3 pixel_TBN;
uniform sampler2D txr_normal;
out layout(location=0) vec4 frag_col;
const vec4 v05=vec4(0.5,0.5,0.5,0.5);
//------------------------------------------------------------------
void main(void)
{
vec4 col;
vec3 normal;
col=(texture2D(txr_normal,pixel_txr.st)-v05)*2.0; // normal/bump maping
normal=pixel_TBN*col.xyz;
// col=... other stuff to compute col
frag_col=col;
}
//------------------------------------------------------------------