# 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 ``` 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//.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 ` 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//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//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`).