From 386c9ede78d5ef999972e97ead2429eca9f9eb5b Mon Sep 17 00:00:00 2001 From: Jim Eckerlein Date: Wed, 27 May 2026 16:29:53 +0200 Subject: [PATCH 1/4] fixes #639 --- source/gltf/scene.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/gltf/scene.js b/source/gltf/scene.js index 75fccfc7..073769bf 100644 --- a/source/gltf/scene.js +++ b/source/gltf/scene.js @@ -26,15 +26,15 @@ class gltfScene extends GltfObject { const nodeDirty = parentDirty || node.isLocalTransformDirty(); node.dirtyTransform = nodeDirty; node.dirtyScale = false; - if (nodeDirty) { - mat4.multiply(node.worldTransform, parentTransform, node.getLocalTransform()); - mat4.invert(node.inverseWorldTransform, node.worldTransform); - mat4.transpose(node.normalMatrix, node.inverseWorldTransform); - quat.multiply(node.worldQuaternion, parentRotation, node.rotation); - mat4.getScaling(node.worldScale, node.worldTransform); - if (parentScaleDirty || node.animatedPropertyObjects["scale"].dirty) { - node.dirtyScale = true; - } + + mat4.multiply(node.worldTransform, parentTransform, node.getLocalTransform()); + mat4.invert(node.inverseWorldTransform, node.getRenderedWorldTransform()); + mat4.transpose(node.normalMatrix, node.inverseWorldTransform); + quat.multiply(node.worldQuaternion, parentRotation, node.rotation); + mat4.getScaling(node.worldScale, node.getRenderedWorldTransform()); + + if (nodeDirty && (parentScaleDirty || node.animatedPropertyObjects["scale"].dirty)) { + node.dirtyScale = true; } if (nodeDirty && node.instanceMatrices) { @@ -42,7 +42,7 @@ class gltfScene extends GltfObject { for (let i = 0; i < node.instanceMatrices.length; i++) { const instanceTransform = node.instanceMatrices[i]; const instanceWorldTransform = mat4.create(); - mat4.multiply(instanceWorldTransform, node.worldTransform, instanceTransform); + mat4.multiply(instanceWorldTransform, node.getRenderedWorldTransform(), instanceTransform); node.instanceWorldTransforms.push(instanceWorldTransform); } } From 69cdb6eae56665d7e9ab588c16c34dc81d9c7080 Mon Sep 17 00:00:00 2001 From: Jim Eckerlein Date: Tue, 2 Jun 2026 11:57:36 +0200 Subject: [PATCH 2/4] Revert "fixes #639" This reverts commit 386c9ede78d5ef999972e97ead2429eca9f9eb5b. --- source/gltf/scene.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/gltf/scene.js b/source/gltf/scene.js index 073769bf..75fccfc7 100644 --- a/source/gltf/scene.js +++ b/source/gltf/scene.js @@ -26,15 +26,15 @@ class gltfScene extends GltfObject { const nodeDirty = parentDirty || node.isLocalTransformDirty(); node.dirtyTransform = nodeDirty; node.dirtyScale = false; - - mat4.multiply(node.worldTransform, parentTransform, node.getLocalTransform()); - mat4.invert(node.inverseWorldTransform, node.getRenderedWorldTransform()); - mat4.transpose(node.normalMatrix, node.inverseWorldTransform); - quat.multiply(node.worldQuaternion, parentRotation, node.rotation); - mat4.getScaling(node.worldScale, node.getRenderedWorldTransform()); - - if (nodeDirty && (parentScaleDirty || node.animatedPropertyObjects["scale"].dirty)) { - node.dirtyScale = true; + if (nodeDirty) { + mat4.multiply(node.worldTransform, parentTransform, node.getLocalTransform()); + mat4.invert(node.inverseWorldTransform, node.worldTransform); + mat4.transpose(node.normalMatrix, node.inverseWorldTransform); + quat.multiply(node.worldQuaternion, parentRotation, node.rotation); + mat4.getScaling(node.worldScale, node.worldTransform); + if (parentScaleDirty || node.animatedPropertyObjects["scale"].dirty) { + node.dirtyScale = true; + } } if (nodeDirty && node.instanceMatrices) { @@ -42,7 +42,7 @@ class gltfScene extends GltfObject { for (let i = 0; i < node.instanceMatrices.length; i++) { const instanceTransform = node.instanceMatrices[i]; const instanceWorldTransform = mat4.create(); - mat4.multiply(instanceWorldTransform, node.getRenderedWorldTransform(), instanceTransform); + mat4.multiply(instanceWorldTransform, node.worldTransform, instanceTransform); node.instanceWorldTransforms.push(instanceWorldTransform); } } From 521ba218ca9d6a7ce4214dcf2b77501a23d0ee69 Mon Sep 17 00:00:00 2001 From: Jim Eckerlein Date: Tue, 2 Jun 2026 12:07:58 +0200 Subject: [PATCH 3/4] compute normal matrix in renderer --- source/Renderer/renderer.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/Renderer/renderer.js b/source/Renderer/renderer.js index 5ea8b213..3a19687e 100644 --- a/source/Renderer/renderer.js +++ b/source/Renderer/renderer.js @@ -1139,11 +1139,15 @@ class gltfRenderer { } const worldTransform = node.getRenderedWorldTransform(); + + const normalMatrix = mat4.create(); + mat4.invert(normalMatrix, node.getRenderedWorldTransform()); + mat4.transpose(normalMatrix, normalMatrix); // update model dependant matrices once per node this.shader.updateUniform("u_ViewProjectionMatrix", viewProjectionMatrix); this.shader.updateUniform("u_ModelMatrix", worldTransform); - this.shader.updateUniform("u_NormalMatrix", node.normalMatrix, false); + this.shader.updateUniform("u_NormalMatrix", normalMatrix, false); this.shader.updateUniform("u_Exposure", state.renderingParameters.exposure, false); this.shader.updateUniform("u_Camera", this.currentCameraPosition, false); if (renderpassConfiguration.picking) { From 09e8a9af72a127ad0a80d99510db7027d4278215 Mon Sep 17 00:00:00 2001 From: Jim Eckerlein Date: Tue, 2 Jun 2026 12:09:01 +0200 Subject: [PATCH 4/4] remove normal matrix class member from node --- source/gltf/node.js | 1 - source/gltf/scene.js | 1 - 2 files changed, 2 deletions(-) diff --git a/source/gltf/node.js b/source/gltf/node.js index 764e13b7..c0637c91 100644 --- a/source/gltf/node.js +++ b/source/gltf/node.js @@ -29,7 +29,6 @@ class gltfNode extends GltfObject { this.worldQuaternion = quat.create(); this.worldScale = vec3.create(); this.inverseWorldTransform = mat4.create(); - this.normalMatrix = mat4.create(); this.light = undefined; this.instanceMatrices = undefined; this.instanceWorldTransforms = undefined; diff --git a/source/gltf/scene.js b/source/gltf/scene.js index 75fccfc7..14763b88 100644 --- a/source/gltf/scene.js +++ b/source/gltf/scene.js @@ -29,7 +29,6 @@ class gltfScene extends GltfObject { if (nodeDirty) { mat4.multiply(node.worldTransform, parentTransform, node.getLocalTransform()); mat4.invert(node.inverseWorldTransform, node.worldTransform); - mat4.transpose(node.normalMatrix, node.inverseWorldTransform); quat.multiply(node.worldQuaternion, parentRotation, node.rotation); mat4.getScaling(node.worldScale, node.worldTransform); if (parentScaleDirty || node.animatedPropertyObjects["scale"].dirty) {