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
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.
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.
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.
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::Reinhardin 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.
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.
Cdoubles 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).
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_SIZEat 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.
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 tofalsein 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).
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
Rgba16Floatand 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.
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.
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.
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.
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.
# 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.