e5f3636b42
- meshes/cube: procedural checkerboard -> uv_texture.jpg (8x8 UV grid) - meshes/pbr: floor -> ground.jpeg, bump cube -> cave.jpg + caveNormal.jpg (normal map pre-encoded via sRGB OETF to cancel the GPU sRGB decode) - lights/shadow: ground -> ground.jpeg, cube -> uv_texture.jpg - effects/demo: ground -> ground.jpeg, cube -> uv_texture.jpg - effects/fog: ground -> ground.jpeg (tiled 80x80), cubes -> stonewall.jpg - effects/dof: ground -> ground.jpeg, cubes -> uv_texture.jpg - cameras/culling: shared cube mesh -> uv_texture.jpg - add lib/examples/assets/textures/ (19 assets, 6.5 MB) - document assets + usage in examples READMEs, docs/user/examples.md, docs/user/meshes/materials.md (CARGO_MANIFEST_DIR pattern, sRGB caveat)
55 lines
2.0 KiB
Markdown
55 lines
2.0 KiB
Markdown
# Cameras & Camera-Driven Rendering
|
||
|
||
Examples where the **camera** drives what gets rendered.
|
||
|
||
| Example | Run command | What it shows |
|
||
|---------|-------------|---------------|
|
||
| `culling` | `cargo run -p wsg-lib --example culling` | GPU-driven frustum culling: a 15×15 grid of UV-atlas cubes, off-frustum objects skipped |
|
||
|
||
> All commands run from the repo root.
|
||
|
||
The frustum is defined by the camera's view-projection matrix, so frustum
|
||
culling is inherently a camera concept: move the camera and the set of drawn
|
||
objects changes — with **zero CPU cost** (the GPU decides in a compute pass).
|
||
|
||
---
|
||
|
||
## `culling` — GPU Frustum Culling
|
||
|
||
A grid of **15×15 = 225 cubes** is placed on a large floor. The shared cube
|
||
mesh is textured with the `uv_texture.jpg` atlas — the colourful labelled
|
||
cells make it obvious exactly which cubes the GPU draws and which it culls.
|
||
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).
|
||
>
|
||
> The GPU-driven pipeline (compute matrices → culling → indirect draws) is
|
||
> documented in [`docs/tech/ARCHI_CPU_GPU.md`](../../../docs/tech/ARCHI_CPU_GPU.md)
|
||
> and [`docs/user/cameras/gpu-driven.md`](../../../docs/user/cameras/gpu-driven.md).
|