Skip to main content
GitHub

Open Illumination Effects to inspect the actual render-stack stages through separate accordions for clustered deferred lighting, GTAO, diffuse global illumination, screen-space reflections, clustered volumetric scattering, and crepuscular god rays. Expand a section to adjust its quality, transport, or temporal-history controls without scrolling through one flattened settings list. Dedicated Adaptive HDR Exposure and Cinematic HDR Bloom sections make the camera response and highlight pyramid independently inspectable. The reusable pipelines default to full-resolution intermediate buffers, while Illumination Lab starts its GTAO, diffuse global illumination, screen-space reflections, and clustered volumetric lighting controls at a performance-balanced half resolution. Raise Buffer Resolution to 1 when maximum edge fidelity matters more than history memory and shaded pixels. When an effect is disabled and is not the selected diagnostic, the renderer drops that effect pipeline and its intermediate and history targets instead of merely hiding its final contribution.

Why This Is Not Visualization City

Illumination Lab prioritizes physically based deferred light transport: one G-buffer feeds compute-clustered direct lighting, GTAO, diffuse global illumination, shared screen-space reflections, and light-driven atmospheric scattering.

Effects: Visualization City instead demonstrates a broader hybrid effects stack, including cascaded, spot, point, and contact shadows; lower-cost SSAO; simple height fog; outlines; temporal AA; and motion blur. The two examples intentionally share the same SSR implementation rather than duplicating a "standard" and an "advanced" reflection effect.

What to inspect

  • Drag the canvas to orbit the scene and use the mouse wheel or trackpad to zoom. Disable Auto Orbit to inspect individual materials, chrome accents, or reflected light paths.
  • Columns increase roughness from mirror-like highlights to broad matte lobes.
  • Rows increase metalness while changing the base material family, so dielectric diffuse response gives way to colored metallic reflections.
  • The orbiting emissive markers are the same point lights consumed by the deferred resolve. Raise Point Lights toward 512 to stress compute-built cluster lists without redrawing the material geometry.
  • Cyan, magenta, and amber emitter panels transfer their color onto nearby floors, walls, and diffuse spheres. Compare Indirect Lighting against the final image to isolate the actual screen-space bounce contribution.
  • Base Color, Normals, Roughness, Metallic, Emissive, and Depth expose the actual G-buffer channels rather than a recreated diagnostic view. Cluster Occupancy shows the per-pixel cluster list pressure as a cold-to-hot heatmap. Ambient Occlusion exposes the denoised, temporally reprojected GTAO visibility buffer. Indirect Lighting isolates diffuse bounced HDR radiance, and Bounce Confidence exposes visible hemisphere-ray coverage. Reflections isolates reflected HDR radiance, while Reflection Confidence makes screen-edge and roughness falloff visible. Volumetric Lighting isolates colored participating-media in-scattering, Volume Transmittance exposes atmospheric extinction, and God Rays isolates the depth-occluded directional shafts.
  • Raise GTAO Radius to make larger-scale creases visible, then use GTAO Intensity and GTAO Strength to separate visibility estimation from how strongly it affects lit color.
  • Tune Bounce Radius, Bounce Intensity, Bounce Strength, Bounce Rays, and Ray Steps to compare subtle indirect fill against more saturated local color transfer. Bounce History trades responsiveness for temporally stable low-noise indirect light.
  • Adjust SSR Strength, SSR Intensity, SSR Distance, and SSR Samples to compare mirror-sharp hits against rough glossy lobes. SSR History shows the temporal trade-off between responsive animated highlights and stable low-noise reflections.
  • Adjust Fog Density, Height Falloff, Light Halos, Sun Shafts, and Scattering Direction to distinguish height-based extinction, clustered point-light scattering, directional occlusion, and anisotropic phase response. Volume History controls atmospheric temporal stability.
  • Expand Crepuscular God Rays and adjust Ray Intensity, Ray Reach, Ray Persistence, and Ray Samples to reveal radial sunlight shafts behind visible occluders. The radial source follows the same world-space sun used by deferred and volumetric lighting as the camera orbits, and disappears when that sun moves behind the camera.
  • Select HDR Luminance to inspect the logarithmic scene-luminance heat map. Tune Middle Gray, adaptation speeds, and exposure limits to watch the virtual camera respond to changing lighting.
  • Adjust Highlight Threshold, Glow Intensity, and Glow Radius to spread emissive and specular highlights across a floating-point multiscale bloom pyramid without clipping HDR color.

Render stack

The geometry pass writes the standard GBuffer scene color, encoded view normal/roughness, velocity, and depth channels plus two named material extras:

TargetPayload
baseColorMetallicLinear base color in RGB and metalness in A.
emissiveOcclusionLinear emissive color in RGB and ambient occlusion in A.

ClusteredLightGrid first bins each view-space point-light sphere into a 16 × 9 × 24 screen/log-depth grid. createClusteredDeferredLightingShaderPassPipeline() then reads those material targets and normally evaluates the current pixel's compact retained cluster list. If a cluster overflows, the opaque resolve instead scans all active point lights to preserve direct-light correctness. It reconstructs view-space position from depth, evaluates Cook-Torrance lighting, and writes HDR color back into the normal ordered shader-pass chain. createDeferredAmbientLightingShaderPassPipeline() separately extracts the linear ambient contribution from the same material attachments. createGTAOShaderPassPipeline({composition: 'ambient-only'}) then analytically integrates horizon angles at the configured buffer resolution over the unchanged depth and view-normal attachments, rotates and jitters sampling across animation frames, reprojects the previous AO result through the velocity buffer, rejects disocclusions with depth history, and applies a depth-aware separable blur. Its final composite attenuates only the isolated ambient contribution, leaving directional and point lights plus emissive materials untouched. createSSGIShaderPassPipeline() traces cosine-weighted hemisphere rays through that lit scene, gathers nearby colored radiance, reprojects indirect-light history, rejects disocclusions in linearized view depth, and applies two depth/normal-aware denoising passes before composing the diffuse bounce. createSSRShaderPassPipeline() then launches roughness-jittered reflection rays into the lit scene, reprojects reflection history through G-buffer velocity, rejects depth disocclusions, applies a roughness-adaptive depth/normal-aware blur, and adds the result back into previous. createClusteredVolumetricLightingShaderPassPipeline() then integrates real clustered point lights and occluded directional light through exponential height fog, applies Beer-Lambert extinction and an anisotropic phase function, traces radial camera-depth visibility toward the projected scene sun for crepuscular god rays, and ranks a bounded nearby-light set from the compute-retained cluster candidates. Unlike the opaque resolve's overflow fallback, volumetric ray marching never scans all active lights. It stabilizes in-scattering at the configured buffer resolution by reprojecting empty space with current/previous camera matrices, applying G-buffer velocity to opaque surfaces, and rejecting disocclusions against compact linear-depth history, then composites the participating medium over the existing opaque result. createHDRAutoExposureShaderPassPipeline() builds a center-weighted logarithmic luminance pyramid, adapts a persistent GPU exposure target without CPU readback, and applies the current camera response. createBloomShaderPassPipeline() thresholds HDR samples, successively low-pass filters, blurs, and combines bright highlights across three rgba16float scales. A final display pass tone maps the result or selects a G-buffer/cluster/AO/bounce/reflection/ volume debug view.

The point-light positions are transformed to view space on the CPU and packed with makeDeferredPointLightBufferData() into two vec4f records per light:

position.xyz, range, color.rgb, intensity

That fixed representation keeps the example focused on the deferred boundary: geometry owns material capture, compute owns light assignment, the lighting pass owns direct light, and later effects such as GTAO and SSR consume the unchanged depth, normal, velocity, and scene-color contract. SSGI and SSR then add complementary diffuse and specular indirect lighting without drawing the contributing geometry a second time.

For a comparison with environment-map reflections, SSAO, baseline deferred lighting, and other composable effect alternatives, see Rendering Techniques and Tradeoffs.