},
“indices” : 0,
“material” : 0,
“mode” : 4
}
]
}
]
…
注意glTF只支持tangent,不支持同时存tangent和bitangent,我猜测原因是bitangent能够通过normal和tangent叉乘得到,所以不需要存,如果能存的话也能少掉这个叉乘的计算,但模型也会变大些。
将光照计算转换到切线空间
要得到法向纹理中的法向量,要对法向纹理进行采样,最简单直接的做法就是在fragment shader中对一个片元计算光照时从法向纹理中采样得到法向量,再用TBN矩阵转换到模型坐标系,最终用模型矩阵转到世界坐标系中计算光照,但由于fragment shader执行的次数一般比较多,就会导致这样的TBN矩阵变换次数较多,有一个常用的优化方法,就是将光照计算放到切线空间中:
// vertex shader
…
out vec3 v_tangentLightPos;
out vec3 v_tangentViewPos;
out vec3 v_tangentFragPos;
void main() {
…
mat3 normalMatrix = transpose(inverse(mat3(u_modelMatrix)));
// 将TBN三个坐标轴转到世界坐标系
mat3 worldTBNMatrix = mat3(
normalize(normalMatrix * tangent),
normalize(normalMatrix * bitangent),
normalize(normalMatrix * a_normal.xyz)
);