Files
wsg/lib/examples
Jérôme Bousquié e5f3636b42 examples: apply real texture assets to multi-mesh examples
- 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)
2026-09-26 10:49:13 +02:00
..

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/ Geometry, materials, file import, low-level workflow simple, cube, pbr, import, manual
lights/ Light types, shadow mapping, emissive materials shadow, shadow_test, spot_test, emissive
cameras/ Camera-driven rendering (frustum culling) culling
effects/ HDR, tone mapping, post-process, full showcase demo, bloom, hdr, msaa, fog, dof

Running an example

Example names are stable — from the repo root:

cargo run -p wsg-lib --example <name>

Examples gated behind a Cargo feature need the feature too:

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/. 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:

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 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):
    [[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).