# Rendering workflow (GI + post-process volumes) Step-by-step guide for game teams managing look development without Rust changes. ## Mental model 1. **Project defaults** — `assets/project.ron` → `rendering` section (GI mode, lighting, post FX). 2. **Post-process volumes** — scene actors with local overrides (rooms, biomes, boss arenas). 3. **Requested profile** — the active viewport camera always uses `ActiveCameraRenderProfile` (project + blended volumes), whether it is the editor fly camera or the possessed player camera. 4. **Effective stack** — `EffectiveRenderStack` records requested GI, effective GI, and fallback reason for renderer sync and diagnostics. See [ADR 0013](../adr/0013-rendering-tiers-and-post-process-volumes.md) for tier policy and crate boundaries, and [ADR 0016](../adr/0016-unified-rendering-contract.md) for the requested/effective stack contract. ## Project defaults 1. **Edit → Project Settings** 2. Expand **Global Illumination**, **Lighting**, and **Post Process** sections. 3. Click **Apply** (updates runtime; **Save to disk** writes `assets/project.ron`). | Section | Key controls | |---------|----------------| | GI | `GiMode`: Auto / Forward / Solari; status line shows RT fallback | | Lighting | Ambient, sun lux, shadow cascades | | Post Process | HDR, exposure mode (Manual EV100 / Auto), auto exposure speeds, bloom, TAA, SSAO, atmosphere, fog | ## Post-process volumes ### Create - **Scene → Create → Post Process Volume** - Asset Browser → Built-ins → **Post Process Volume** (drag into the viewport) - Command palette: `rendering.create_volume` ### Inspector (inherit / override) Each FX field uses **Override** checkbox: - **Unchecked** — inherits project value (shown greyed as *Inherited: …*). - **Checked** — local value; **Reset to project** per field. Volume fields: label (HUD), priority, blend distance, half extents (local-space AABB). ### Rendering panel **Window → Rendering** tabs: | Tab | Purpose | |-----|---------| | Active Camera | Resolved GI path, exposure, fog, FX flags, contributing volumes | | Project | Read-only `project.ron` summary + link to Project Settings | | Volumes | All volumes in level (priority sort, select/focus) | Viewport overlays: **GI badge** (Forward / Solari), **volume HUD** when inside a volume. ## GI modes | Mode | Behavior | |------|----------| | Auto | Startup default: Solari when RT GPU support is available; Forward otherwise | | Forward | Bevy Forward PBR with HDR/TAA/SSAO/atmosphere/shadows | | Solari | Request Solari; the camera attaches Bevy Solari when RT support is available | Solari in Bevy 0.18 samples directional lights and emissive meshes. Point and spot lights require the normal PBR light pass, so `LightDesc` point/spot components are runtime-disabled while Solari is active. The component remains in the scene, the inspector shows an unsupported message, and hydration strips/skips the Bevy `PointLight` / `SpotLight` until authors switch the light to Directional or switch GI to Forward. The viewport resolves Hybrid Auto through **`EffectiveRenderStack`**: requested Solari keeps project meshes eligible for raytracing and attaches Bevy Solari when RT support is available. Effective GI falls back to **Forward** only when RT is unavailable. Effective Solari forces an HDR camera target even if project HDR is off, because Bevy Solari writes to the main texture through a storage binding and sRGB textures are invalid for that use. Primitive hydration generates tangents so built-in boxes/spheres can enter Solari BLAS/TLAS; imported/custom meshes still need TriangleList geometry, POSITION/NORMAL/UV_0/TANGENT attributes, and U32 indices. The Rendering panel reports the exact fallback reason, Solari-compatible asset counts, bind-group state, and compatible light counters. Set `BEVY_FPS_FORCE_SOLARI=1` to force RT feature probing in dev (see README troubleshooting). ## Emissive lighting Material authoring includes emissive color, emissive intensity (nits), and an optional emissive texture. Emissive materials contribute to bloom in Forward PBR and count as Solari-compatible light sources when the material is on eligible project geometry. Use emissive surfaces for area-style indirect light in Solari scenes; use point/spot lights when local direct lighting and shadows are more important. ## Asset folders | Path | Purpose | |------|---------| | `assets/rendering_profiles/*.ron` | Named override bundles (`RenderingProfileAsset`); Apply / Revert in volume inspector | | `assets/post_fx/*.ron` + `.wgsl` | Fullscreen effects (`PostProcessEffectAsset`); picker in volume inspector | | `assets/materials/*.ron` | Material presets, including emissive fields for Solari-compatible surfaces | Shipped examples: `post_fx/vignette.ron`, `post_fx/chromatic_aberration.ron`, `rendering_profiles/cave_dark.ron`, `rendering_profiles/outdoor_haze.ron`, `materials/emissive_panel.ron`. ## Game team checklist - Keep global look in `assets/project.ron`. - Use volumes for rooms/biomes; set `label` for HUD clarity. - Reuse looks via `rendering_profiles/` presets. - Add custom shaders under `assets/post_fx/` — do not fork `camera_fx.rs` for one-off levels. - Prefer `GiMode::Auto` for the default project path. Use `GiMode::Forward` when authoring point/spot lighting or debugging classic shadow maps. - Use emissive material presets for Solari indirect-light contributors; keep helper meshes tagged `RaytracingExcluded`. ## Example level Open `assets/levels/rendering_showcase.scn.ron` for fog, exposure, and vignette volume examples. ## Troubleshooting | Symptom | Check | |---------|-------| | Point/spot weak at max lumens | Outdoor exposure (~12–15 EV100 in Project Settings) needs much higher lumens than indoor (~7 EV100). Bevy’s reference scale is ~1M lumens (`VERY_LARGE_CINEMA_LIGHT`); inspector allows up to 2M. Narrow spot cones for brighter hotspots. For local lights, GI path must be **Forward** (Solari uses directional + emissive only). | | Point/spot controls disabled under GiMode Auto | Auto selected Solari on this GPU. Point/spot `LightDesc` is disabled while Solari is active; switch the light to Directional, use emissive materials, or set GI to Forward. | | Scene sun shadow range wrong vs Project Settings | Scene directionals use `cascade_config_from_rendering`; Apply shadow cascade settings and confirm `sync_scene_directional_shadow_cascades` | | Auto exposure not active | **Rendering → Active Camera**: needs **Exposure: Auto**, HDR on, and GPU compute. Volume **Exposure EV100** override forces manual for that view. | | Viewport black in Lit | Rendering panel → **Runtime lights**, **Stack**, and **Solari raytracing scene**; Collider mode hides meshes | | Solari warming up | Solari raytracing scene readiness: tagged meshes, Solari-compatible mesh assets, render instances, bind group, compatible lights | | Lighting changes do nothing in Solari | Solari samples directional lights and emissive meshes; point/spot `LightDesc` is disabled while Solari is active | | GI badge shows Forward unexpectedly | Solari RT wgpu features unavailable; Rendering → Active Camera tab | | Volume has no effect | Camera inside AABB? Priority vs other volumes? Overrides enabled? | | Custom FX missing | RON path in volume matches `assets/post_fx/`; shader path in RON | Command palette: `rendering.select_volumes_at_camera`, `rendering.focus_active_volumes`.