Files
wsg/lib/examples/README.md
T
Jérôme Bousquié 83daeb4c7d readmes
2026-09-25 14:54:27 +02:00

341 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WSG Examples
Each example is self-contained and demonstrates **one effect or feature** of the library. All use the declarative API (`AppBuilder` + `AppHandler`).
## Running an example
```sh
cargo run -p wsg-lib --example <name>
```
| Example | Effect demonstrated |
|---------|-------------------|
| `demo` | Full showcase (all effects combined) |
| `bloom` | Post-process bloom (glow around bright areas) |
| `hdr` | HDR + Tone Mapping (ACES) + exposure control |
| `emissive` | Emissive materials (increasing intensities 0 → 4.0) |
| `shadow` | Shadow mapping (directional shadow) |
| `culling` | GPU-driven culling (15×15 grid, off-frustum objects skipped) |
| `msaa` | MSAA 4× (multisample anti-aliasing, smooth edges) |
| `fog` | Distance fog (3 modes: linear, exp, exp²) |
| `dof` | Depth of Field (cinematic bokeh, focus presets) |
| `pbr` | PBR metallic/roughness + normal mapping |
| `manual` | Low-level workflow (Context + Renderer + PipelineCache) |
| `import` | OBJ file import (non-graphical, stdout) |
---
## `demo` — Full Showcase
Combines **all** effects: LOD primitives, procedural textures, lights
(directional + point + spot), shadows, HDR/ACES, exposure, emissive, bloom, culling.
```sh
cargo run -p wsg-lib --example demo
```
### Keys
| Key | Action |
|-----|--------|
| Drag (LMB) | Orbit camera |
| Wheel | Zoom |
| `R` | Reset camera |
| `1` / `2` / `3` | Presets: front / side / top |
| `+` / `-` | Exposure ×1.3 / ÷1.3 |
| `0` | Reset exposure |
---
## `bloom` — Post-process Bloom
Two emissive spheres (orange intensity 2.0, blue intensity 3.0) produce a visible
halo. The cube and floor serve as reference (non-emissive).
Bloom is a 4-pass GPU pipeline: threshold → blur H → blur V → composite.
```sh
cargo run -p wsg-lib --example bloom
```
### Keys
| Key | Action |
|-----|--------|
| Drag (LMB) | Orbit camera |
| Wheel | Zoom |
| `R` | Reset camera |
| `+` / `-` | **Bloom threshold** +0.1 / −0.1 |
| `[` / `]` | **Bloom intensity** +0.1 / −0.1 |
| `I` / `O` | **Bloom radius** +0.5 / −0.5 |
| `E` / `Q` | Exposure ×1.3 / ÷1.3 |
| `0` | Reset exposure |
### What to observe
- **Low threshold** (0.0): the entire image "blooms" (very diffuse effect).
- **High threshold** (2.0+): only the bright emissive spheres produce glow.
- **Intensity 0.0**: no visible glow (even though the threshold extracts pixels).
- **Large radius** (10+): the glow spreads over a large area.
---
## `hdr` — HDR + Tone Mapping
Demonstrates HDR rendering with the ACES Filmic curve. Three objects:
- **Cube**: normal lighting (no emissive) — LDR reference.
- **Bright sphere** (emissive 3.0): without HDR, it would be clamped to white.
With ACES, highlights "roll off" smoothly toward white.
- **Dark sphere** (emissive 0.3): stays dark even at high exposure.
```sh
cargo run -p wsg-lib --example hdr
```
### Keys
| Key | Action |
|-----|--------|
| Drag (LMB) | Orbit camera |
| Wheel | Zoom |
| `R` | Reset camera |
| `E` | **Exposure ×1.3** (brighter) |
| `Q` | **Exposure ÷1.3** (darker) |
| `0` | Reset exposure to 1.0 |
### What to observe
- At exposure 1.0: the bright sphere is white but with detail (ACES rolloff).
- At high exposure (E×E×E): the scene brightens, the bright sphere stays white
(saturated), but the cube gains detail.
- At low exposure (Q×Q): everything darkens, the bright sphere becomes orange
(HDR values > 1.0 are compressed).
> **Note**: the tone mapper is compiled into the pipeline at build time. To compare
> ACES vs Reinhard, change `ToneMapper::Aces` → `ToneMapper::Reinhard` in the source.
---
## `emissive` — Emissive Materials
Five spheres in a row with increasing emissive intensities:
| Sphere | Color | Intensity | Effect |
|--------|-------|-----------|--------|
| 1 | Gray | 0.0 | No glow (reference) |
| 2 | Orange | 0.5 | Slight glow |
| 3 | Yellow | 1.0 | Visible glow |
| 4 | Green | 2.0 | HDR glow (beyond 1.0) |
| 5 | Blue | 4.0 | Intense glow (saturation) |
With HDR, intensities > 1.0 produce a true "glow" (values exceed
[0,1] in linear space). Without HDR, they would be clamped to white.
```sh
cargo run -p wsg-lib --example emissive
```
### Keys
| Key | Action |
|-----|--------|
| Drag (LMB) | Orbit camera |
| Wheel | Zoom |
| `R` | Reset camera |
| `E` / `Q` | Exposure ×1.3 / ÷1.3 |
| `0` | Reset exposure |
| `C` | **Cycle emissive multiplier** (1× → 2× → 0.5× → ...) |
### What to observe
- Sphere 1 (intensity 0) is simply lit by the directional light.
- Spheres 2-5 glow with their own light, independent of scene lighting.
- `C` doubles or halves all intensities simultaneously (to see the HDR effect).
---
## `shadow` — Shadow Mapping
Four objects (cube, sphere, cone, cylinder) on a floor, lit by a directional light
that casts shadows. Shadow quality is controlled by `ShadowConfig` (map size, anti-acne bias).
```sh
cargo run -p wsg-lib --example shadow
```
### Keys
| Key | Action |
|-----|--------|
| Drag (LMB) | Orbit camera |
| Wheel | Zoom |
| `R` | Reset camera |
| `1` | Front view |
| `2` | Side view |
| `3` | **Top view** (see shadow shapes clearly) |
| `L` | Change light direction (3 presets) |
### What to observe
- The cube rotates slowly → its shadow moves on the floor.
- The sphere has a smooth shadow/light transition (soft terminator).
- The cone produces a distinct triangular shadow.
- In top view (`3`), you see the exact shape of projected shadows.
- Shadow map size (1024 default) determines resolution:
modify `SHADOW_MAP_SIZE` at the top of the file to test 256 (pixelated) or 2048 (sharp).
---
## `culling` — GPU Frustum Culling
A grid of **15×15 = 225 cubes** is placed on a large floor. The GPU-driven culling
(compute shader) determines which cubes are visible in the camera frustum and zeros
their indirect draw args — **zero CPU cost**.
```sh
cargo run -p wsg-lib --example culling
```
### Keys
| Key | Action |
|-----|--------|
| Drag (LMB) | Orbit camera (look around) |
| Wheel | Zoom in/out |
| `R` | Reset (top view) |
| `1` | Front view (cubes behind are culled) |
| `2` | Side view |
| `3` | **Top view** (see the full grid) |
### What to observe
- In top view (`3`): the entire grid is visible.
- Orbit to 90°: cubes behind the camera **are not drawn** (culled).
- Zoom very close: only cubes near the near plane are rendered.
- Cubes rotate slowly (staggered phases) → culling is dynamic
(a cube can enter/leave the frustum during a frame).
> **Note**: culling is enabled via `AppBuilder::with_culling(true)`. Changing
> it to `false` in the source disables culling (all cubes are always drawn, even off-screen).
---
## `msaa` — MSAA 4× (Anti-aliasing)
Demonstrates multisample anti-aliasing: object edges (cube, sphere)
are smooth instead of "stair-stepped". The scene contains a cube (sharp edges),
a sphere (curved silhouette), and a small cube near the camera (maximum aliasing).
```sh
cargo run -p wsg-lib --example msaa
```
### Keys
| Key | Action |
|-----|--------|
| Drag (LMB) | Orbit camera |
| Wheel | Zoom |
| `R` | Reset camera |
| `M` | Show sample count |
### To compare with/without MSAA
Remove the `.with_msaa(4)` line in the source and recompile: the scene is
identical, only the edges differ (stair-stepped vs smooth).
> **Note**: MSAA is a build-time setting (multisample texture allocation).
> It works independently of HDR: with HDR, the MSAA texture is `Rgba16Float`
> and resolves into the HDR texture before bloom/TM.
---
## `fog` — Distance Fog
Demonstrates the 3 fog modes: **linear**, **exponential**, **exponential²**.
The scene contains a row of cubes receding into the distance and scattered spheres
on a large floor plane. Fog blends objects toward a background color,
creating the illusion of an infinite world.
```sh
cargo run -p wsg-lib --example fog --features "all-prims"
```
**Keys**: `1` = linear, `2` = exp, `3` = exp², `4` = off, `R` = reset.
> Fog is applied in the main fragment shader (after lighting, before tone mapping).
> It uses the Euclidean distance from the fragment to the camera.
---
## `dof` — Depth of Field (cinematic bokeh)
Demonstrates depth of field blur: an object at the focus plane stays sharp while
foreground and background blur according to their distance from the focus plane.
Creates a natural attention effect (cinematic style).
The scene contains 20 cubes in a row along Z (z=3 to z=-25.5) and 5 spheres to the
sides, on a floor plane. Focus presets at 3m / 8m / 15m.
```sh
cargo run -p wsg-lib --example dof --features "all-prims"
```
**Keys**: `1` = cinematic, `2` = subtle, `3` = focus 3m, `4` = focus 15m, `5` = off, `R` = reset.
> DoF operates in linear HDR (after bloom, before tone mapping). Two passes:
> CoC (depth → per-pixel blur radius) then 12-tap disc blur with variable radius.
---
## `pbr` — PBR Metallic/Roughness + Normal Mapping
Demonstrates the Cook-Torrance PBR workflow: GGX distribution + Smith geometry +
Schlick Fresnel + hemispheric IBL + normal mapping.
```sh
cargo run -p wsg-lib --example pbr
```
| Key | Action |
|-----|--------|
| Drag (LMB) | Orbit camera |
| Wheel | Zoom |
| `R` | Reset camera |
Scene: 6 PBR materials (mirror metal, smooth plastic, rusty metal, ceramic, bump map, matte floor).
The bump-map cube shows procedural sin-wave surface detail.
---
## `manual` — Low-level Workflow
Demonstrates the API **without** the `App` facade: direct use of `Context`,
`Renderer`, `PipelineCache`, `Mesh`, `Material`. Renders a colored quad (unlit).
Useful for understanding what the `App` facade encapsulates.
```sh
cargo run -p wsg-lib --example manual
```
No keys — static render (unlit quad, 4 colors).
---
## `import` — OBJ File Import
**Non-graphical** example: parses a `.obj` file and prints statistics
(vertex count, normals, UVs, indices, bounding box) to stdout.
```sh
# With a file:
cargo run -p wsg-lib --example import --features import-obj -- /path/to/model.obj
# Without argument (demo triangle):
cargo run -p wsg-lib --example import --features import-obj
```
No keys — runs and exits.