正常映射并保持切线

时间:2017-09-19 09:10:00

标签: opengl math matrix graphics glsl

假设你有一个带有法线贴图的3D网格。网格还拥有切线,bitangents和法线。

从切线,bitangents和法线,您可以构建TBN矩阵,该矩阵是将切线空间转换为世界空间的矩阵。这样,为了让真正的正常,你只需做类似的事情:

mat3 TBN = mat3(tangent, bitangent, normal);
vec3 realNormal = TBN * normalFromTheNormalMap;

但是,如何从这个系统中获得真正的切线和bitangent?

1 个答案:

答案 0 :(得分:2)

你必须Orthogonalize向量。 Orthogonalization的常用方法是Gram–Schmidt Orthonormalization

该算法使用的情况是,2个向量的 dot 乘积等于2个向量之间角度的余弦乘以两个向量的幅度(长度)向量。

dot( N, T ) == length( N ) * length( T ) * cos( angle_N_T ) 

接下来,2个单位向量(归一化向量)的 dot 乘积等于2个向量之间角度的余弦,因为单位长度矢量是1。

uN = normalize( A )
uT = normalize( B )
cos( angle_T_N ) == dot( uT, uN )

enter image description here

如果realNormal是规范化向量(其长度为1)且tangentbinormal是正交的,则realTangentrealBinormal可以按这样计算:

realTangent  = normalize( tangent - realNormal * dot(tangent,  realNormal) );
realBinormal = binormal - realNormal * dot(binormal, realNormal);
realBinormal = normalize( realBinormal - realTangent * dot(realBinormal, realTangent) );

如果tangentbinormal也是规范化的向量,那么normalize函数可以用源向量的点积和 real 矢量:

realTangent   = tangent - realNormal * dot(tangent,  realNormal);
realTangent  /= dot(tangent, realTangent);
realBinormal  = binormal - realNormal * dot(binormal, realNormal);
realBinormal  = realBinormal - realTangent * dot(realBinormal, realTangent);
realBinormal /= dot(binormal, realBinormal);

进一步查看How to calculate Tangent and Binormal?