在顶点着色器和片元着色器中计算TBN矩阵有何区别?

3
我认为我们可以在顶点着色器和片元着色器中计算TBN矩阵。
// calculate in vs
varying mat3 vTbnMatrix;
void main() {
  vec3 n = normalMatrix * aNormal;
  vec3 t = normalMatrix * vec3(aTangent.xyz);
  vec3 b = cross(n, t) * aTangent.w;
  vTbnMatrix = mat3(t, b, n);
}

// calculate in fs
varying vec3 vNormal; // transformed by normalMatrix
varying vec3 vTangent; // transformed by normalMatrix
varying vec3 vBitantent;
void main() {
  mat3 tbnMatrix = mat3(vTangent, vBitangent, vNormal);
}

有什么不同吗?我认为我们可以在顶点着色器中计算TBN矩阵,因为这样可以加快程序的速度。

但是当我深入研究THREE.js和PlayCanvas引擎的源代码时,它们都在片段着色器中计算TBN矩阵。

在片段着色器中计算的优势是什么?

1个回答

2
TBN矩阵在理论上应该是正交的。
在three.js中,法线、切线和副切线作为varyings传递,在原始图元上进行插值,重新归一化,并在片段着色器中构建TBN矩阵。这样,矩阵列就满足(1)长度为单位,(2)近似正交。
你可以在片段着色器中计算副切线,以强制其与插值的法线和切线正交,但这样做可能并没有太大的区别,因为插值的法线和切线本来就不保证正交。
three.js r.102

要使TBN矩阵正交,我们可以使用Gram-Schmidt过程,对吧?而且我认为它可以在顶点着色器和片段着色器中处理... - user2331095
1
正如我所说,TBN矩阵的列必须具有单位长度。这意味着需要在片段着色器中重新归一化列。 - WestLangley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接