Skip to content

Commit

Permalink
Refactoring of TBN shader part of lit-shader (#7389)
Browse files Browse the repository at this point in the history
Co-authored-by: Martin Valigursky <[email protected]>
  • Loading branch information
mvaligursky and Martin Valigursky authored Feb 27, 2025
1 parent b132b62 commit c88b2b3
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 89 deletions.
4 changes: 0 additions & 4 deletions src/scene/shader-lib/chunks-wgsl/chunks-wgsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ import sphericalPS from './common/frag/spherical.js';
// import startNineSlicedTiledPS from './lit/frag/startNineSlicedTiled.js';
// import tangentBinormalVS from './lit/vert/tangentBinormal.js';
// import TBNPS from './lit/frag/TBN.js';
// import TBNderivativePS from './lit/frag/TBNderivative.js';
// import TBNObjectSpacePS from './lit/frag/TBNObjectSpace.js';
// import thicknessPS from './standard/frag/thickness.js';
import tonemappingPS from './common/frag/tonemapping/tonemapping.js';
import tonemappingAcesPS from './common/frag/tonemapping/tonemappingAces.js';
Expand Down Expand Up @@ -388,8 +386,6 @@ const shaderChunksWGSL = {
// startNineSlicedTiledPS,
// tangentBinormalVS,
// TBNPS,
// TBNderivativePS,
// TBNObjectSpacePS,
// thicknessPS,
tonemappingPS,
tonemappingAcesPS,
Expand Down
6 changes: 3 additions & 3 deletions src/scene/shader-lib/chunks/chunk-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ const chunkVersions = {
shadowEVSMPS: CHUNKAPI_1_62,
spotPS: CHUNKAPI_1_62,
TBNPS: CHUNKAPI_1_62,
TBNObjectSpacePS: CHUNKAPI_1_62,
TBNderivativePS: CHUNKAPI_1_62,

endPS: CHUNKAPI_1_65,
metalnessModulatePS: CHUNKAPI_1_65,
Expand Down Expand Up @@ -120,7 +118,9 @@ const removedChunks = {
baseVS: CHUNKAPI_2_6,
baseNineSlicedVS: CHUNKAPI_2_6,
viewNormalVS: CHUNKAPI_2_6,
lightmapDirAddPS: CHUNKAPI_2_6
lightmapDirAddPS: CHUNKAPI_2_6,
TBNObjectSpacePS: CHUNKAPI_2_6,
TBNderivativePS: CHUNKAPI_2_6
};

// compare two "major.minor" semantic version strings and return true if a is a smaller version than b.
Expand Down
4 changes: 0 additions & 4 deletions src/scene/shader-lib/chunks/chunks.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ import startNineSlicedPS from './lit/frag/startNineSliced.js';
import startNineSlicedTiledPS from './lit/frag/startNineSlicedTiled.js';
import tangentBinormalVS from './lit/vert/tangentBinormal.js';
import TBNPS from './lit/frag/TBN.js';
import TBNderivativePS from './lit/frag/TBNderivative.js';
import TBNObjectSpacePS from './lit/frag/TBNObjectSpace.js';
import thicknessPS from './standard/frag/thickness.js';
import tonemappingPS from './common/frag/tonemapping/tonemapping.js';
import tonemappingAcesPS from './common/frag/tonemapping/tonemappingAces.js';
Expand Down Expand Up @@ -388,8 +386,6 @@ const shaderChunks = {
startNineSlicedTiledPS,
tangentBinormalVS,
TBNPS,
TBNderivativePS,
TBNObjectSpacePS,
thicknessPS,
tonemappingPS,
tonemappingAcesPS,
Expand Down
69 changes: 68 additions & 1 deletion src/scene/shader-lib/chunks/lit/frag/TBN.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,72 @@
export default /* glsl */`
#ifdef LIT_TANGENTS
#define TBN_TANGENTS
#else
#if defined(LIT_USE_NORMALS) || defined(LIT_USE_CLEARCOAT_NORMALS)
#define TBN_DERIVATIVES
#endif
#endif
#if defined(TBN_DERIVATIVES)
uniform float tbnBasis;
#endif
void getTBN(vec3 tangent, vec3 binormal, vec3 normal) {
dTBN = mat3(normalize(tangent), normalize(binormal), normalize(normal));
#ifdef TBN_TANGENTS // tangents / binormals based TBN
dTBN = mat3(normalize(tangent), normalize(binormal), normalize(normal));
#elif defined(TBN_DERIVATIVES) // derivatives based TBN
vec2 uv = {lightingUv};
// get edge vectors of the pixel triangle
vec3 dp1 = dFdx( vPositionW );
vec3 dp2 = dFdy( vPositionW );
vec2 duv1 = dFdx( uv );
vec2 duv2 = dFdy( uv );
// solve the linear system
vec3 dp2perp = cross( dp2, normal );
vec3 dp1perp = cross( normal, dp1 );
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
// construct a scale-invariant frame
float denom = max( dot(T,T), dot(B,B) );
float invmax = (denom == 0.0) ? 0.0 : tbnBasis / sqrt( denom );
dTBN = mat3(T * invmax, -B * invmax, normal );
#else // object space TBN
vec3 B = cross(normal, vObjectSpaceUpW);
vec3 T = cross(normal, B);
if (dot(B,B)==0.0) // deal with case when vObjectSpaceUpW normal are parallel
{
float major=max(max(normal.x, normal.y), normal.z);
if (normal.x == major)
{
B = cross(normal, vec3(0,1,0));
T = cross(normal, B);
}
else if (normal.y == major)
{
B = cross(normal, vec3(0,0,1));
T = cross(normal, B);
}
else if (normal.z == major)
{
B = cross(normal, vec3(1,0,0));
T = cross(normal, B);
}
}
dTBN = mat3(normalize(T), normalize(B), normalize(normal));
#endif
}
`;
30 changes: 0 additions & 30 deletions src/scene/shader-lib/chunks/lit/frag/TBNObjectSpace.js

This file was deleted.

25 changes: 0 additions & 25 deletions src/scene/shader-lib/chunks/lit/frag/TBNderivative.js

This file was deleted.

48 changes: 26 additions & 22 deletions src/scene/shader-lib/programs/lit-shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,8 @@ class LitShader {
const backend = new ChunkBuilder();
const code = new ChunkBuilder();

const hasTBN = this.needsNormal && (options.useNormals || options.useClearCoatNormals || (options.enableGGXSpecular && !options.useHeights));

if (options.useSpecular) {
this.fDefineSet(true, 'LIT_SPECULAR');
this.fDefineSet(this.reflections, 'LIT_REFLECTIONS');
Expand All @@ -522,6 +524,18 @@ class LitShader {
this.fDefineSet(options.twoSidedLighting, 'LIT_TWO_SIDED_LIGHTING');
this.fDefineSet(options.lightMapEnabled, 'LIT_LIGHTMAP');
this.fDefineSet(options.dirLightMapEnabled, 'LIT_DIR_LIGHTMAP');
this.fDefineSet(hasTBN, 'LIT_TBN');
this.fDefineSet(options.hasTangents, 'LIT_TANGENTS');
this.fDefineSet(options.useNormals, 'LIT_USE_NORMALS');
this.fDefineSet(options.useClearCoatNormals, 'LIT_USE_CLEARCOAT_NORMALS');

// injection defines
this.fDefineSet(true, '{lightingUv}', this.lightingUv ?? ''); // example: vUV0_1

// globals
decl.append(`
mat3 dTBN;
`);

// FRAGMENT SHADER INPUTS: UNIFORMS

Expand Down Expand Up @@ -555,33 +569,23 @@ class LitShader {
#include "lightingPS"
`);

// TBN
const hasTBN = this.needsNormal && (options.useNormals || options.useClearCoatNormals || (options.enableGGXSpecular && !options.useHeights));
func.append(`
if (hasTBN) {
if (options.hasTangents) {
func.append(chunks.TBNPS);
} else {
if (options.useNormals || options.useClearCoatNormals) {
func.append(chunks.TBNderivativePS.replace(/\$UV/g, this.lightingUv));
} else {
func.append(chunks.TBNObjectSpacePS);
}
}
// TBN
#ifdef LIT_TBN
#include "TBNPS"
func.append(`
#ifdef LIT_TWO_SIDED_LIGHTING
#include "twoSidedLightingPS"
#endif
`);
}
#endif
func.append(`
#include "sphericalPS"
#include "decodePS"
#include "gammaPS"
#include "tonemappingPS"
#include "fogPS"
`);

// frontend
Expand Down Expand Up @@ -800,16 +804,17 @@ class LitShader {
code.append(' dBinormalW = vBinormalW;');
}

code.append(' getViewDir();');
if (hasTBN) {
code.append(`
code.append(`
getViewDir();
#ifdef LIT_TBN
getTBN(dTangentW, dBinormalW, dVertexNormalW);
#ifdef LIT_TWO_SIDED_LIGHTING
handleTwoSidedLighting();
#endif
`);
}
#endif
`);
}

// invoke frontend functions
Expand Down Expand Up @@ -1354,7 +1359,6 @@ class LitShader {
const mergedCode = decl.code + func.code + code.code;

// Light inputs
if (mergedCode.includes('dTBN')) structCode += 'mat3 dTBN;\n';
if (mergedCode.includes('dVertexNormalW')) structCode += 'vec3 dVertexNormalW;\n';
if (mergedCode.includes('dTangentW')) structCode += 'vec3 dTangentW;\n';
if (mergedCode.includes('dBinormalW')) structCode += 'vec3 dBinormalW;\n';
Expand Down

0 comments on commit c88b2b3

Please sign in to comment.