From 7a62d8ed7b8dcbad0b82da6fac5dc482bb0c2362 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Tue, 7 Apr 2026 11:19:12 +0200 Subject: [PATCH] Add fog volume mesh configuration in ViewportHost --- src/viewport-three/viewport-host.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/viewport-three/viewport-host.ts b/src/viewport-three/viewport-host.ts index 06641cc5..6c3a8409 100644 --- a/src/viewport-three/viewport-host.ts +++ b/src/viewport-three/viewport-host.ts @@ -27,6 +27,7 @@ import { Quaternion, Raycaster, Scene, + ShaderMaterial, SphereGeometry, Spherical, TorusGeometry, @@ -282,6 +283,7 @@ export class ViewportHost { private readonly cameraForward = new Vector3(); private readonly cameraRight = new Vector3(); private readonly cameraUp = new Vector3(); + private readonly fogLocalCameraPosition = new Vector3(); private readonly cameraSpherical = new Spherical(); private readonly gridHelpers: Record = { xz: new GridHelper(40, 40, 0xcf8354, 0x4e596b), @@ -2317,6 +2319,8 @@ export class ViewportHost { const mesh = new Mesh(geometry, materials); const brushSelected = isBrushSelected(selection, brush.id); + this.configureFogVolumeMesh(mesh, materials); + mesh.userData.brushId = brush.id; mesh.castShadow = false; mesh.receiveShadow = false; @@ -2353,6 +2357,25 @@ export class ViewportHost { this.applyShadowState(); } + private configureFogVolumeMesh(mesh: Mesh, materials: Material[]) { + const fogMaterials = materials.filter( + (material): material is ShaderMaterial => material instanceof ShaderMaterial && material.uniforms["localCameraPosition"] !== undefined + ); + + if (fogMaterials.length === 0) { + mesh.onBeforeRender = null; + return; + } + + mesh.onBeforeRender = (_renderer, _scene, camera) => { + const localCameraPosition = mesh.worldToLocal(this.fogLocalCameraPosition.copy(camera.position)); + + for (const material of fogMaterials) { + (material.uniforms["localCameraPosition"] as { value: Vector3 }).value.copy(localCameraPosition); + } + }; + } + private rebuildEntityMarkers(document: SceneDocument, selection: EditorSelection) { this.clearEntityMarkers();