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)
96 lines
4.4 KiB
Markdown
96 lines
4.4 KiB
Markdown
# WSG Examples
|
||
|
||
The examples are organized into **four category folders**, one per theme. Each
|
||
folder has its own `README.md` documenting its examples in detail (what they
|
||
demonstrate, how to run them, keyboard controls, what to observe).
|
||
|
||
| Folder | Theme | Examples |
|
||
|--------|-------|----------|
|
||
| [meshes/](meshes/README.md) | Geometry, materials, file import, low-level workflow | `simple`, `cube`, `pbr`, `import`, `manual` |
|
||
| [lights/](lights/README.md) | Light types, shadow mapping, emissive materials | `shadow`, `shadow_test`, `spot_test`, `emissive` |
|
||
| [cameras/](cameras/README.md) | Camera-driven rendering (frustum culling) | `culling` |
|
||
| [effects/](effects/README.md) | HDR, tone mapping, post-process, full showcase | `demo`, `bloom`, `hdr`, `msaa`, `fog`, `dof` |
|
||
|
||
## Running an example
|
||
|
||
Example **names are stable** — from the repo root:
|
||
|
||
```sh
|
||
cargo run -p wsg-lib --example <name>
|
||
```
|
||
|
||
Examples gated behind a Cargo feature need the feature too:
|
||
|
||
```sh
|
||
cargo run -p wsg-lib --example import --features import-obj
|
||
```
|
||
|
||
All examples are **self-contained**: hard-coded geometries, and textures that are
|
||
either procedural or shipped in [`assets/textures/`](assets/textures/). All use the
|
||
declarative API (`AppBuilder` + `AppHandler`) except `manual`, which demonstrates
|
||
the low-level workflow instead.
|
||
|
||
## Texture assets
|
||
|
||
A few examples (the multi-mesh / multi-effect ones) use real image files from
|
||
`assets/textures/`, loaded with `Texture::from_file`. The paths are resolved
|
||
against `CARGO_MANIFEST_DIR` at compile time, so the examples work from **any
|
||
working directory**:
|
||
|
||
```rust
|
||
const TEXTURES: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/examples/assets/textures");
|
||
Texture::from_file(&device, &queue, "label", &format!("{TEXTURES}/ground.jpeg"))
|
||
```
|
||
|
||
Assets used by the examples:
|
||
|
||
| Asset | Size | Used by | Role |
|
||
|-------|------|---------|------|
|
||
| `uv_texture.jpg` | 437×438 | `cube`, `demo`, `shadow`, `dof`, `culling` | 8×8 UV atlas visualization (labelled cells + corner coordinates) — makes UV mapping and culling decisions explicit |
|
||
| `ground.jpeg` | 512×512 | `demo`, `pbr`, `shadow`, `fog`, `dof` | Seamless ground albedo, tiled via the `Repeat` sampler |
|
||
| `stonewall.jpg` | 300×225 | `fog` | Distinctive cube texture — the fog falloff reads clearly on it |
|
||
| `cave.jpg` + `caveNormal.jpg` | 600×450 | `pbr` | Albedo + normal-map pair for the PBR normal-mapping demo |
|
||
|
||
The remaining assets in the folder (`rock.jpg`, `seamlessRoad.jpg`, `stalag.jpg` /
|
||
`stalagNormal.jpg`, `stars1.jpg`, sprite/heightmap PNGs, …) are available for
|
||
experiments. Two notes:
|
||
|
||
- `Texture` uploads to `Rgba8UnormSrgb` — correct for **albedo** maps (the GPU
|
||
sRGB-decodes on sample). A **normal map** is linear data, so `pbr` pre-encodes
|
||
its channels with the sRGB OETF before upload (`load_normal_map`): the GPU
|
||
decode then restores the original values (EOTF∘OETF = identity).
|
||
- The texture sampler is `Linear` + `Repeat`, so any texture tiles automatically
|
||
when UVs exceed [0,1] (the 80×80 fog floor uses this to tile `ground.jpeg`).
|
||
|
||
> **Where do the files live?** Examples live in subfolders
|
||
> (`examples/<folder>/<name>.rs`). Cargo only auto-discovers top-level
|
||
> `examples/*.rs`, so every example is declared explicitly in
|
||
> [`lib/Cargo.toml`](../Cargo.toml) with its `path`. This keeps
|
||
> `--example <name>` working while allowing the folder organization.
|
||
|
||
## Suggested learning path
|
||
|
||
1. `simple` — the minimal declarative workflow (flat unlit quad, ~15 lines)
|
||
2. `cube` — the 3D MVP: a textured, lit, spinning cube
|
||
3. `pbr` — PBR materials and normal mapping
|
||
4. `spot_test`, `shadow_test` — isolated light and shadow behavior
|
||
5. `hdr` → `emissive` → `bloom` — the HDR chain, step by step
|
||
6. `culling` — GPU-driven frustum culling
|
||
7. `demo` — everything combined
|
||
8. `manual` — what the `App` facade actually encapsulates
|
||
|
||
## Adding your own example
|
||
|
||
1. Create `lib/examples/<folder>/my_example.rs` (pick the matching category;
|
||
add a new folder + README if needed).
|
||
2. Declare it in `lib/Cargo.toml` (Cargo won't discover it otherwise):
|
||
```toml
|
||
[[example]]
|
||
name = "my_example"
|
||
path = "examples/<folder>/my_example.rs"
|
||
```
|
||
3. Keep it **self-contained**: hard-coded geometries; textures are procedural
|
||
or come from `assets/textures/` (resolved via `CARGO_MANIFEST_DIR`, see
|
||
*Texture assets* above).
|
||
4. Document it in the folder's `README.md` (and in `docs/user/examples.md`).
|