diff --git a/examples/src/examples/graphics/normals-and-tangents.mjs b/examples/src/examples/graphics/normals-and-tangents.mjs index 9720422e507..12d32b94daa 100644 --- a/examples/src/examples/graphics/normals-and-tangents.mjs +++ b/examples/src/examples/graphics/normals-and-tangents.mjs @@ -37,7 +37,7 @@ async function example({ canvas, deviceType, glslangPath, twgslPath, assetPath, app.init(createOptions); const assets = { - statue: new pc.Asset('statue', 'container', { url: assetPath + 'models/NormalTangentTest.glb' }), + model: new pc.Asset('model', 'container', { url: assetPath + 'models/NormalTangentTest.glb' }), script: new pc.Asset('script', 'script', { url: scriptsPath + 'camera/orbit-camera.js' }), helipad: new pc.Asset('helipad-env-atlas', 'texture', { url: assetPath + 'cubemaps/helipad-env-atlas.png' }, { type: pc.TEXTURETYPE_RGBP, mipmaps: false }), }; @@ -72,10 +72,17 @@ async function example({ canvas, deviceType, glslangPath, twgslPath, assetPath, app.scene.skyboxRotation = new pc.Quat().setFromEulerAngles(0, 70, 0); app.scene.skyboxIntensity = 1.5; - // Create an entity hierarchy representing the statue - const statueEntity = assets.statue.resource.instantiateRenderEntity(); - statueEntity.setLocalEulerAngles(0, 90, 0); - app.root.addChild(statueEntity); + const leftEntity = assets.model.resource.instantiateRenderEntity(); + leftEntity.setLocalEulerAngles(0, 90, 0); + leftEntity.setPosition(0, 0, 1); + leftEntity.setLocalScale(0.8, 0.8, 0.8); + app.root.addChild(leftEntity); + + const rightEntity = assets.model.resource.instantiateRenderEntity(); + rightEntity.setLocalEulerAngles(0, 90, 0); + rightEntity.setPosition(0, 0, -1); + rightEntity.setLocalScale(-0.8, -0.8, -0.8); + app.root.addChild(rightEntity); // Create a camera with an orbit camera script const camera = new pc.Entity(); diff --git a/src/scene/shader-lib/chunks/lit/frag/TBN.js b/src/scene/shader-lib/chunks/lit/frag/TBN.js index 8ac6a907f0f..46079ea1573 100644 --- a/src/scene/shader-lib/chunks/lit/frag/TBN.js +++ b/src/scene/shader-lib/chunks/lit/frag/TBN.js @@ -1,5 +1,13 @@ export default /* glsl */` void getTBN(vec3 tangent, vec3 binormal, vec3 normal) { - dTBN = mat3(normalize(tangent), normalize(binormal), normalize(normal)); + #ifdef TWO_SIDED_LIGHTING + dTBN = mat3( + normalize((gl_FrontFacing ? tangent : -tangent ) * twoSidedLightingNegScaleFactor), + normalize((gl_FrontFacing ? binormal : -binormal) * twoSidedLightingNegScaleFactor), + normalize((gl_FrontFacing ? normal : -normal ) * twoSidedLightingNegScaleFactor) + ); + #else + dTBN = mat3(normalize(tangent), normalize(binormal), normalize(normal)); + #endif } `; diff --git a/src/scene/shader-lib/chunks/lit/frag/TBNderivative.js b/src/scene/shader-lib/chunks/lit/frag/TBNderivative.js index 1a1f4ccb753..6781b389a40 100644 --- a/src/scene/shader-lib/chunks/lit/frag/TBNderivative.js +++ b/src/scene/shader-lib/chunks/lit/frag/TBNderivative.js @@ -22,7 +22,7 @@ void getTBN(vec3 tangent, vec3 binormal, vec3 normal) { float invmax = (denom == 0.0) ? 0.0 : tbnBasis / sqrt( denom ); #ifdef TWO_SIDED_LIGHTING - dTBN = mat3(T * invmax, -B * invmax, gl_FrontFacing ? normal : -normal); + dTBN = mat3(T * invmax, -B * invmax, (gl_FrontFacing ? normal : -normal) * twoSidedLightingNegScaleFactor); #else dTBN = mat3(T * invmax, -B * invmax, normal); #endif diff --git a/src/scene/shader-lib/chunks/lit/frag/TBNfast.js b/src/scene/shader-lib/chunks/lit/frag/TBNfast.js index d4da6edbcdb..aff211bb22b 100644 --- a/src/scene/shader-lib/chunks/lit/frag/TBNfast.js +++ b/src/scene/shader-lib/chunks/lit/frag/TBNfast.js @@ -1,5 +1,13 @@ export default /* glsl */` void getTBN(vec3 tangent, vec3 binormal, vec3 normal) { - dTBN = mat3(tangent, binormal, normal); + #ifdef TWO_SIDED_LIGHTING + dTBN = mat3( + (gl_FrontFacing ? tangent : -tangent ) * twoSidedLightingNegScaleFactor, + (gl_FrontFacing ? binormal : -binormal) * twoSidedLightingNegScaleFactor, + (gl_FrontFacing ? normal : -normal ) * twoSidedLightingNegScaleFactor + ); + #else + dTBN = mat3(tangent, binormal, normal); + #endif } `; diff --git a/src/scene/shader-lib/programs/lit-shader.js b/src/scene/shader-lib/programs/lit-shader.js index d758a8129b8..72c3db3b306 100644 --- a/src/scene/shader-lib/programs/lit-shader.js +++ b/src/scene/shader-lib/programs/lit-shader.js @@ -985,20 +985,11 @@ class LitShader { code.append(this._fsGetStartCode(code, device, chunks, options)); if (this.needsNormal) { - if (options.twoSidedLighting) { - code.append(" dVertexNormalW = normalize(gl_FrontFacing ? vNormalW * twoSidedLightingNegScaleFactor : -vNormalW * twoSidedLightingNegScaleFactor);"); - } else { - code.append(" dVertexNormalW = normalize(vNormalW);"); - } + code.append(" dVertexNormalW = normalize(vNormalW);"); if ((options.useHeights || options.useNormals) && options.hasTangents) { - if (options.twoSidedLighting) { - code.append(" dTangentW = gl_FrontFacing ? vTangentW * twoSidedLightingNegScaleFactor : -vTangentW * twoSidedLightingNegScaleFactor;"); - code.append(" dBinormalW = gl_FrontFacing ? vBinormalW * twoSidedLightingNegScaleFactor : -vBinormalW * twoSidedLightingNegScaleFactor;"); - } else { - code.append(" dTangentW = vTangentW;"); - code.append(" dBinormalW = vBinormalW;"); - } + code.append(" dTangentW = vTangentW;"); + code.append(" dBinormalW = vBinormalW;"); } code.append(" getViewDir();");