diff --git a/src/rendering/tsl/VolumetricFog.ts b/src/rendering/tsl/VolumetricFog.ts index 90d40aec..bef23d5b 100644 --- a/src/rendering/tsl/VolumetricFog.ts +++ b/src/rendering/tsl/VolumetricFog.ts @@ -203,9 +203,15 @@ export function createVolumetricFogNode( * Update camera matrices (call before render) */ updateCamera: (cam: THREE.PerspectiveCamera) => { + // Ensure camera matrices are current before copying + // (camera position may have changed but matrices not yet updated) + cam.updateMatrixWorld(); + cam.updateProjectionMatrix(); + uCameraNear.value = cam.near; uCameraFar.value = cam.far; - uCameraPos.value.copy(cam.position); + // Extract world position from matrixWorld for consistency with world reconstruction + uCameraPos.value.setFromMatrixPosition(cam.matrixWorld); uInverseProjection.value.copy(cam.projectionMatrixInverse); uInverseView.value.copy(cam.matrixWorld); }, diff --git a/src/rendering/tsl/effects/EffectPasses.ts b/src/rendering/tsl/effects/EffectPasses.ts index f6dfbbcb..6d4fca72 100644 --- a/src/rendering/tsl/effects/EffectPasses.ts +++ b/src/rendering/tsl/effects/EffectPasses.ts @@ -1045,6 +1045,11 @@ export function createFogOfWarPass( }; const updateCamera = (cam: THREE.PerspectiveCamera) => { + // Ensure camera matrices are current before copying + // (camera position may have changed but matrices not yet updated) + cam.updateMatrixWorld(); + cam.updateProjectionMatrix(); + // Update camera parameters for world position reconstruction uCameraNear.value = cam.near; uCameraFar.value = cam.far; @@ -1052,8 +1057,9 @@ export function createFogOfWarPass( uInverseProjection.value.copy(cam.projectionMatrixInverse); // Camera world matrix transforms view-space to world-space uCameraWorldMatrix.value.copy(cam.matrixWorld); - // Direct camera position for volumetric fog - uCameraPos.value.copy(cam.position); + // Extract world position from matrixWorld for consistency with world reconstruction + // (using camera.position directly would give local position if camera has a parent) + uCameraPos.value.setFromMatrixPosition(cam.matrixWorld); }; const applyConfig = (config: Partial) => {