diff --git a/packages/viewer/src/components/renderers/zone/zone-renderer.tsx b/packages/viewer/src/components/renderers/zone/zone-renderer.tsx
index a0556c32..abb14a9b 100644
--- a/packages/viewer/src/components/renderers/zone/zone-renderer.tsx
+++ b/packages/viewer/src/components/renderers/zone/zone-renderer.tsx
@@ -5,6 +5,7 @@ import { BufferGeometry, Color, DoubleSide, Float32BufferAttribute, type Group,
import { color, float, uniform, uv } from 'three/tsl'
import { MeshBasicNodeMaterial } from 'three/webgpu'
import { useNodeEvents } from '../../../hooks/use-node-events'
+import { ZONE_LAYER } from '../../../lib/layers'
const Y_OFFSET = 0.01
const WALL_HEIGHT = 2.3
@@ -239,13 +240,13 @@ export const ZoneRenderer = ({ node }: { node: ZoneNode }) => {
rotation={[-Math.PI / 2, 0, 0]}
material={floorMaterial}
name="floor"
- layers={2}
+ layers={ZONE_LAYER}
>
{/* Wall borders with gradient */}
-
+
)
}
diff --git a/packages/viewer/src/components/viewer/post-processing.tsx b/packages/viewer/src/components/viewer/post-processing.tsx
index 5bb2d711..9539ed57 100644
--- a/packages/viewer/src/components/viewer/post-processing.tsx
+++ b/packages/viewer/src/components/viewer/post-processing.tsx
@@ -1,5 +1,5 @@
import { useFrame, useThree } from '@react-three/fiber'
-import { useEffect, useRef, useState } from 'react'
+import { useEffect, useMemo, useRef, useState } from 'react'
import { Color, Layers, UnsignedByteType } from 'three'
import { outline } from 'three/addons/tsl/display/OutlineNode.js'
import { ssgi } from 'three/addons/tsl/display/SSGINode.js'
@@ -25,6 +25,7 @@ import {
import { RenderPipeline, type WebGPURenderer } from 'three/webgpu'
import useViewer from '../../store/use-viewer'
+import { SCENE_LAYER, ZONE_LAYER } from '../../lib/layers'
// SSGI Parameters - adjust these to fine-tune global illumination and ambient occlusion
export const SSGI_PARAMS = {
@@ -51,15 +52,20 @@ const PostProcessingPasses = () => {
const hasPipelineErrorRef = useRef(false)
const [isInitialized, setIsInitialized] = useState(false)
- const theme = useViewer((s) => s.theme)
-
// Background color uniform — updated every frame via lerp, read by the TSL pipeline.
// Initialised from the current theme so there's no flash on first render.
- const initBg = theme === 'dark' ? DARK_BG : LIGHT_BG
+ const initBg = useViewer.getState().theme === 'dark' ? DARK_BG : LIGHT_BG
const bgUniform = useRef(uniform(new Color(initBg)))
const bgCurrent = useRef(new Color(initBg))
const bgTarget = useRef(new Color())
+ const zoneLayers = useMemo(() => {
+ const l = new Layers()
+ l.enable(ZONE_LAYER)
+ l.disable(SCENE_LAYER)
+ return l
+ }, [])
+
useEffect(() => {
let mounted = true
@@ -125,18 +131,8 @@ const PostProcessingPasses = () => {
return colorToDirection(scenePassNormal.sample(uv))
})
- // camera.layers.disable(0)
- // camera.layers.disable(1)
- // camera.layers.enable(2) // Enable layer 2 for zone rendering
const zonePass = pass(scene, camera)
- // camera.layers.enable(0) // Disable layer 2 for main scene rendering
- // camera.layers.enable(1) // Disable layer 2 for main scene rendering
- // camera.layers.disable(2) // Disable layer 2 for main scene rendering
-
- const layers: Layers = new Layers()
- layers.enable(2) // Enable layer 2 for zone rendering
- layers.disable(0)
- zonePass.setLayers(layers)
+ zonePass.setLayers(zoneLayers)
// SSGI Pass (cast to PerspectiveCamera for SSGI)
const giPass = ssgi(scenePassColor, scenePassDepth, sceneNormal, camera as any)
@@ -260,11 +256,11 @@ const PostProcessingPasses = () => {
}
renderPipelineRef.current = null
}
- }, [renderer, scene, camera, isInitialized])
+ }, [renderer, scene, camera, isInitialized, zoneLayers])
useFrame((_, delta) => {
// Animate background colour toward the current theme target (same lerp as AnimatedBackground)
- bgTarget.current.set(theme === 'dark' ? DARK_BG : LIGHT_BG)
+ bgTarget.current.set(useViewer.getState().theme === 'dark' ? DARK_BG : LIGHT_BG)
bgCurrent.current.lerp(bgTarget.current, Math.min(delta, 0.1) * 4)
bgUniform.current.value.copy(bgCurrent.current)
diff --git a/packages/viewer/src/index.ts b/packages/viewer/src/index.ts
index d97a508c..e7e4f714 100644
--- a/packages/viewer/src/index.ts
+++ b/packages/viewer/src/index.ts
@@ -1,5 +1,6 @@
export { default as Viewer } from './components/viewer'
export { default as useViewer } from './store/use-viewer'
export { ASSETS_CDN_URL, resolveAssetUrl, resolveCdnUrl } from './lib/asset-url'
+export { SCENE_LAYER, ZONE_LAYER } from './lib/layers'
export { InteractiveSystem } from './systems/interactive/interactive-system'
export { snapLevelsToTruePositions } from './systems/level/level-utils'
\ No newline at end of file
diff --git a/packages/viewer/src/lib/layers.ts b/packages/viewer/src/lib/layers.ts
new file mode 100644
index 00000000..b7aa789d
--- /dev/null
+++ b/packages/viewer/src/lib/layers.ts
@@ -0,0 +1,5 @@
+/** Default Three.js layer for main scene geometry. */
+export const SCENE_LAYER = 0
+
+/** Layer used for zone rendering (floor fills and wall borders). */
+export const ZONE_LAYER = 2