# Study III · Light held in stone

This iteration adds three authored light studies, shadow-aware air, a reflected courtyard, and material variation to the Woven atrium. All scene geometry and surface maps remain local and deterministic.

## Composition

Morning veil uses low pale-gold sunlight and long shadows. The last light lowers and warms the sun, emphasizing garnet cloth and dark arcade silhouettes. Silver hour switches direction and colour toward cooler stone and brighter gallery edges. Buttons apply complete sun, exposure, indirect-strength and air-density settings; changing a sun/exposure/air slider marks the study custom. Camera position is preserved when comparing lighting.

Two sagging linen shades introduce overhead silhouettes and real shadow apertures. Stone now varies roughness as well as colour and relief. Fabric uses a repeating embroidered rosette, raised borders and a distinct roughness response for the woven ground and ornament. Shared maps are disposed exactly once. A new At the water camera is at 1.25m, and the slow passage includes a lower section beside the basin.

## Atmosphere stage

`src/framework/atmosphere.js` wraps Three.js r186 GodraysNode, bilateral filtering, and depth-aware compositing. It raymarches the directional light's actual shadow map at half screen resolution: columns, ceilings and linen shades occlude its samples. Draft/balanced/fine use 24/40/64 steps. The composited beauty image enters the existing TRAA resolve, so air and opaque surfaces share the temporal stabilization path. Raw mode omits that resolve.

Density is adjustable and maximum accumulation is limited to preserve contrast. Clear air bypasses the raymarch/filter/composite graph. Direct, AO and voxel diagnostic views also bypass atmosphere. WebGL direct-preview has these controls disabled. This is an integrated upstream screen-space volumetric approximation, not an independent volume renderer or a fully physical participating-medium simulation. Transparent surfaces do not supply reliable opaque depth, and disocclusion/motion still need the dedicated quality study.

## Planar pool

`src/framework/reflections.js` owns a clipped, mirrored camera at half resolution, using Three.js ReflectorNode. Fresnel-like angular weighting blends the reflection into a dark water tint. Recursive reflection bounces and MSAA are disabled. The surface is in a separate layer excluded from voxel collection, while the original basin remains in the transport scene. The runtime removes it and disposes its camera render targets on scene replacement or shutdown.

The result reflects current geometry and sky rather than an image painted into the pool. It is a static planar surface: there are no fluid waves, refraction, reflected volumetric transport or independently traced specular GI. Reflection lighting uses the upstream scene render. The toggle bypasses that extra camera render. Non-pool scenes hide the control; fallback disables it.

## Verification

`make check` tests geometry, deterministic maps, disposal and settings, then builds the app. `npm run test:browser` exercises both actual WebGPU and forced direct-only WebGL, presets, all output/quality modes, camera rail interruption, effects, resize, full screen, mobile layout and export. Fixed-camera, raw, bloom-free captures compare clear versus shadowed air, reflection versus basin, and indirect on versus off. The comparison checks visible contribution and retained contrast; it is not a radiometric or GPU-cost measurement. Artifacts are saved under artifacts/.

GPU timestamps, a standalone volume implementation, specular comparison against SSR, and rigorous temporal/disocclusion qualification remain tracked work. The switches allow effects to be removed when the extra passes are too expensive on a particular device.

## Sources

- [Three.js Godrays example](https://github.com/mrdoob/three.js/blob/r186/examples/webgpu_postprocessing_godrays.html), GodraysNode, BilateralBlurNode and depthAwareBlend, MIT; GodraysNode credits three-good-godrays.
- [Three.js ReflectorNode](https://github.com/mrdoob/three.js/blob/r186/src/nodes/utils/ReflectorNode.js), MIT.
