简体   繁体   中英

Calculate TBN matrix in vertex shader vs fragment shader?

I think we can calculate TBN matrix in both vertex shader and fragment shader.

// 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);
}

What's the difference? I think we can calculate TBN matrix in the vertex shader as it can speed up the program.

But when I dive into the source code of THREE.js and PlayCanvas engine, they both calculate TBN matrix in the fragment shader.

What's the advantage of calculating in the fragment shader?

The TBN matrix should, in theory, be orthonormal.

In three.js, the normal, tangent, and bi-tangent are passed as varyings, interpolated across the face of the primitive, renormalized, and the TBN matrix is constructed in the fragment shader. This way, the matrix columns are (1) of unit length, and (2) presumably close to orthogonal.

You could compute the bi-tangent in the fragment shader, instead, to force it to be orthogonal to the interpolated normal and tangent, but doing so may not make that much difference, as the interpolated normal and tangent are not guaranteed to be orthogonal anyway.

three.js r.102

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM