From d550e9d3b217fcbd90888adca6be628d7efb2e0b Mon Sep 17 00:00:00 2001 From: WestLangley Date: Tue, 7 Apr 2026 17:10:56 -0400 Subject: [PATCH 1/2] rename inverseTransformDirection() --- examples/jsm/helpers/LightProbeHelper.js | 9 +++++---- src/renderers/shaders/ShaderChunk/common.glsl.js | 7 +++---- .../shaders/ShaderChunk/envmap_fragment.glsl.js | 2 +- .../ShaderChunk/envmap_physical_pars_fragment.glsl.js | 4 ++-- src/renderers/shaders/ShaderChunk/envmap_vertex.glsl.js | 2 +- .../shaders/ShaderChunk/lights_pars_begin.glsl.js | 2 +- .../shaders/ShaderChunk/shadowmap_vertex.glsl.js | 2 +- .../shaders/ShaderChunk/transmission_fragment.glsl.js | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/jsm/helpers/LightProbeHelper.js b/examples/jsm/helpers/LightProbeHelper.js index e6da80faa45945..1f9e375a11d370 100644 --- a/examples/jsm/helpers/LightProbeHelper.js +++ b/examples/jsm/helpers/LightProbeHelper.js @@ -58,11 +58,12 @@ class LightProbeHelper extends Mesh { #define RECIPROCAL_PI 0.318309886 - vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) { - // matrix is assumed to be orthogonal + vec3 transformNormalByInverseViewMatrix( in vec3 normal, in mat4 viewMatrix ) { - return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz ); + // upper-left 3x3 of view matrix is assumed to be orthogonal + + return normalize( ( vec4( normal, 0.0 ) * viewMatrix ).xyz ); } @@ -101,7 +102,7 @@ class LightProbeHelper extends Mesh { vec3 normal = normalize( vNormal ); - vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); + vec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix ); vec3 irradiance = shGetIrradianceAt( worldNormal, sh ); diff --git a/src/renderers/shaders/ShaderChunk/common.glsl.js b/src/renderers/shaders/ShaderChunk/common.glsl.js index 8c452c97bb87c9..d2559d176611d2 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl.js +++ b/src/renderers/shaders/ShaderChunk/common.glsl.js @@ -64,12 +64,11 @@ vec3 transformDirection( in vec3 dir, in mat4 matrix ) { } -vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) { +vec3 transformNormalByInverseViewMatrix( in vec3 normal, in mat4 viewMatrix ) { - // dir can be either a direction vector or a normal vector - // upper-left 3x3 of matrix is assumed to be orthogonal + // upper-left 3x3 of view matrix is assumed to be orthogonal - return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); + return normalize( ( vec4( normal, 0.0 ) * viewMatrix ).xyz ); } diff --git a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js index fd753723ac337f..d06111180167fe 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js @@ -16,7 +16,7 @@ export default /* glsl */` } // Transforming Normal Vectors with the Inverse Transformation - vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); + vec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix ); #ifdef ENVMAP_MODE_REFLECTION diff --git a/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js index 1fb80e4d41c98a..164f8a288a7f27 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js @@ -5,7 +5,7 @@ export default /* glsl */` #ifdef ENVMAP_TYPE_CUBE_UV - vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); + vec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix ); vec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 ); @@ -28,7 +28,7 @@ export default /* glsl */` // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane. reflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) ); - reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); + reflectVec = transformNormalByInverseViewMatrix( reflectVec, viewMatrix ); vec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness ); diff --git a/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl.js index 537c94f1bbde6e..14a9df4d8b2f45 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl.js +++ b/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl.js @@ -19,7 +19,7 @@ export default /* glsl */` } - vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix ); + vec3 worldNormal = transformNormalByInverseViewMatrix( transformedNormal, viewMatrix ); #ifdef ENVMAP_MODE_REFLECTION diff --git a/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js b/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js index 62961a8487c1e2..a95044f85cf725 100644 --- a/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +++ b/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js @@ -37,7 +37,7 @@ vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) { vec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) { - vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); + vec3 worldNormal = transformNormalByInverseViewMatrix( normal, viewMatrix ); vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe ); diff --git a/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js b/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js index 1f4dd067ca048c..df52b9e624de3b 100644 --- a/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +++ b/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js @@ -3,7 +3,7 @@ export default /* glsl */` #if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 ) // Offsetting the position used for querying occlusion along the world normal can be used to reduce shadow acne. - vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix ); + vec3 shadowWorldNormal = transformNormalByInverseViewMatrix( transformedNormal, viewMatrix ); vec4 shadowWorldPosition; #endif diff --git a/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js index 1bbf86c20a3adb..e77c9f8c757743 100644 --- a/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js @@ -21,7 +21,7 @@ export default /* glsl */` vec3 pos = vWorldPosition; vec3 v = normalize( cameraPosition - pos ); - vec3 n = inverseTransformDirection( normal, viewMatrix ); + vec3 n = transformNormalByInverseViewMatrix( normal, viewMatrix ); vec4 transmitted = getIBLVolumeRefraction( n, v, material.roughness, material.diffuseContribution, material.specularColorBlended, material.specularF90, From 6e2ed3d8b323dc8a75f4a68f82fa7fa820f00a11 Mon Sep 17 00:00:00 2001 From: WestLangley Date: Tue, 7 Apr 2026 18:34:51 -0400 Subject: [PATCH 2/2] add transformDirectionByInverseViewMatrix() --- src/renderers/shaders/ShaderChunk/common.glsl.js | 8 ++++++++ .../ShaderChunk/envmap_physical_pars_fragment.glsl.js | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/renderers/shaders/ShaderChunk/common.glsl.js b/src/renderers/shaders/ShaderChunk/common.glsl.js index d2559d176611d2..6f199b4c7ba59e 100644 --- a/src/renderers/shaders/ShaderChunk/common.glsl.js +++ b/src/renderers/shaders/ShaderChunk/common.glsl.js @@ -72,6 +72,14 @@ vec3 transformNormalByInverseViewMatrix( in vec3 normal, in mat4 viewMatrix ) { } +vec3 transformDirectionByInverseViewMatrix( in vec3 dir, in mat4 viewMatrix ) { + + // upper-left 3x3 of view matrix is assumed to be orthogonal + + return normalize( ( vec4( dir, 0.0 ) * viewMatrix ).xyz ); + +} + bool isPerspectiveMatrix( mat4 m ) { return m[ 2 ][ 3 ] == - 1.0; diff --git a/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js index 164f8a288a7f27..39d62f0f50bfeb 100644 --- a/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js @@ -28,7 +28,7 @@ export default /* glsl */` // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane. reflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) ); - reflectVec = transformNormalByInverseViewMatrix( reflectVec, viewMatrix ); + reflectVec = transformDirectionByInverseViewMatrix( reflectVec, viewMatrix ); vec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );