Вычислить матрицу TBN в вершинном шейдере против фрагментного шейдера? - PullRequest
3 голосов
/ 09 марта 2019

Я думаю, мы можем вычислить матрицу 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 голосов
/ 11 марта 2019

Теоретически матрица TBN должна быть ортонормированной.

В three.js нормаль, касательная и би-касательная передаются как вариации, интерполируются по всей поверхности примитива, перенормируются, и матрица TBN строится в фрагментном шейдере. Таким образом, столбцы матрицы имеют (1) единичную длину и (2) предположительно близкие к ортогональным.

Вы можете вычислить би-тангенс в фрагментном шейдере, вместо этого, чтобы заставить его быть ортогональным к интерполированной нормали и касательной, но это не может иметь большого значения, так как интерполированная нормаль и касательная не гарантируют быть ортогональным в любом случае.

three.js r.102

...