You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Docs: describe the current rendering, controls, and HUD
Update the architecture rendering-pipeline section to the current state
(10-float instance buffer, alpha-blended creatures vs additive food/effects,
health- and size-driven shading, the effects pass, trails/ambient, and the
live Visuals controls) and add a Controls section to the README.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
-**Click** the canvas to seed a burst of life at the cursor; **drag** to pan, **scroll** to zoom, **F** to frame the swarm, **R** to reset, **H** / **Esc** to toggle the panel.
12
+
- The **⚙ panel** tunes the ecosystem (food, breeding, mortality, predators, metabolism), motion & physics, and **Visuals** — Glow, Trails, Size, Brightness, which are instant and purely cosmetic. **Reset / Cull / Bloom** act immediately.
13
+
- A corner **HUD** shows the live population and a sparkline of its boom/bust waves.
Copy file name to clipboardExpand all lines: docs/ARCHITECTURE.md
+7-6Lines changed: 7 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -90,12 +90,13 @@ This split exists because hecs mutation (in-place writes and spawn/despawn) is s
90
90
91
91
The CPU never builds vertex geometry per entity. Instead:
92
92
93
-
1.`WebSimulation::update_entity_buffer()` ([src/lib.rs](../src/lib.rs)) flattens every entity into a packed `f32` buffer — **8 floats each**: `prev_x, prev_y, x, y, radius, r, g, b` — and returns a raw pointer into WASM linear memory (zero-copy).
94
-
2.`entity_count()` returns `buffer.len() / 8`.
95
-
3. The renderer ([src/web/webgpu.rs](../src/web/webgpu.rs)) reinterprets that slice directly as `&[Instance]` (`bytemuck::cast_slice` — the layouts are identical, so there's no per-frame copy), uploads it to a growable instance buffer, and issues a single instanced draw of a unit quad into an **HDR (`rgba16float`) scene target with additive blending**, so overlapping creatures accumulate brightness past 1.0.
96
-
4. Before the creatures, a second instanced draw renders the **food patches** (`update_food_buffer()` → 4 floats each: `x, y, radius, intensity`) into the same HDR scene as dim, soft teal blobs (`food_vs`/`food_fs` in `shader.wgsl`), so the viewer reads the food structure as ambient nourishment beneath the creatures.
97
-
5.`shader.wgsl` does the heavy lifting on the GPU: it interpolates between `prev` and current position for smooth motion between sim steps, applies the world→screen + camera (zoom/pan) transform, and emits an additive bright core + soft halo in the fragment stage.
98
-
6. A bloom post-process ([src/web/postprocess.rs](../src/web/postprocess.rs), `post.wgsl`) turns the HDR scene into the final frame: a **bright-pass** isolates the glowing regions, a **separable Gaussian blur** at quarter resolution widens them, and a **tonemapped composite** adds the bloom back over the scene and maps it into the swapchain. Each pass draws one fullscreen triangle.
93
+
1.`WebSimulation::update_entity_buffer()` ([src/lib.rs](../src/lib.rs)) flattens every entity into a packed `f32` buffer — **10 floats each**: `prev_x, prev_y, x, y, radius, r, g, b, health, style_id` — and returns a raw pointer into WASM linear memory (zero-copy). `health` (energy fraction) and `style_id` (movement type) let the shader make the look reflect the creature's state.
94
+
2.`entity_count()` returns `buffer.len() / 10`.
95
+
3. The renderer ([src/web/webgpu.rs](../src/web/webgpu.rs)) reinterprets that slice directly as `&[Instance]` (`bytemuck::cast_slice` — the layouts are identical, so there's no per-frame copy), uploads it to a growable instance buffer, and issues a single instanced draw of a unit quad into an **HDR (`rgba16float`) scene target**. Creatures use **alpha blending** so dense colonies keep their colour instead of blowing out to white; food and effects (below) draw **additively** so they bloom.
96
+
4. Before the creatures, a second instanced draw renders the **food patches** (`update_food_buffer()` → 4 floats each: `x, y, radius, intensity`) into the HDR scene (`food_vs`/`food_fs` in `shader.wgsl`) as luminous nutrient fields — lush patches glow warm green-gold with a blooming core, grazed-out ones cool to a faint teal — so the food structure reads as the stage the swarm gathers on.
97
+
5.`shader.wgsl` does the heavy lifting on the GPU: it interpolates between `prev` and current position for smooth motion between sim steps, applies the world→screen + camera (zoom/pan) transform, and shapes each creature in the fragment stage — a soft amoeba body whose **size scales with its real radius**, whose **luminance tracks `health`** (thriving cells bloom, the starving dim and fade — so births fade in and deaths fade out for free), with a hot nucleus glint on predators.
98
+
6. After the creatures, an **effects** pass (`update_effect_buffer()` → 6 floats each, `effect_vs`/`effect_fs`) draws transient expanding rings additively: hot-gold predation flashes, green bloom/seed bursts, and a red cull shockwave. The ring animation is interpolated between sim ticks for smoothness.
99
+
7. A bloom post-process ([src/web/postprocess.rs](../src/web/postprocess.rs), `post.wgsl`) turns the HDR scene into the final frame: a **bright-pass** isolates the glowing regions, a **separable Gaussian blur** at quarter resolution widens them, and a **tonemapped composite** adds the bloom back over an ambient nebula + vignette and maps it into the swapchain. A per-frame **trail fade** decays the scene before the creatures redraw, leaving glowing comet tails. The **Glow / Trails / Brightness / Size** sliders feed these stages live via `WebGpuRenderer::set_visual_params` (a group-3 post-params uniform plus the creature-size uniform). Each post pass draws one fullscreen triangle.
0 commit comments