Files
wsg/lib/examples/meshes/README.md
T
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

124 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Meshes, Materials & Import
Examples covering **geometry and materials**: the minimal workflow, the 3D MVP,
PBR shading, file import, and the low-level (non-`App`) workflow.
| Example | Run command | What it shows |
|---------|-------------|---------------|
| `simple` | `cargo run -p wsg-lib --example simple` | The minimal declarative workflow: a flat two-tone quad, **unlit**, rendered automatically |
| `cube` | `cargo run -p wsg-lib --example cube` | The 3D MVP: a textured (`uv_texture.jpg` UV atlas) cube, lit (directional + point + spot), spinning |
| `pbr` | `cargo run -p wsg-lib --example pbr` | PBR metallic/roughness + normal mapping (real `cave.jpg` albedo + `caveNormal.jpg`) |
| `import` | `cargo run -p wsg-lib --example import --features import-obj` | OBJ file import (non-graphical, prints stats to stdout) |
| `manual` | `cargo run -p wsg-lib --example manual` | The **advanced** workflow: `Context`/`Renderer`/`PipelineCache` driven by hand, without the `App` facade |
> All commands run from the repo root. The `import` example additionally
> requires the `import-obj` Cargo feature.
---
## `simple` — Minimal Declarative Workflow
The "15 lines, no wgpu" model: `AppBuilder` creates the window + GPU, and
`App::run` drives the update → render → present loop. The scene renders
**automatically** — the default `AppHandler::render` calls
`app.render_scene(frame.view())`.
The mesh is a flat two-tone quad declared from a `Geometry` (per-vertex
positions + colors) and drawn with the `standard` shader in **unlit** mode
(`renderer.set_unlit(true)`): flat 2D is a special case of 3D, one pipeline for all.
```sh
cargo run -p wsg-lib --example simple
```
No keys — static render.
---
## `cube` — The 3D MVP
A lit unit cube that rotates, **textured** with the `uv_texture.jpg` asset — an
8×8 UV atlas visualization (labelled cells + corner coordinates) that makes
exactly where each face's UVs land visible. The texture is loaded from
`assets/textures/` via `Texture::from_file` (path resolved against
`CARGO_MANIFEST_DIR`), registered by id (`add_texture`) and bound through
`add_material_texture` (diffuse path, bind group `@group(2)`). Follows the
declarative workflow (like `simple`): `AppBuilder` + automatic scene, **no wgpu
import**; the default camera at (0, 0, 3) frames the cube, and `update()`
rotates the entity via `set_entity_transform` each frame.
```sh
cargo run -p wsg-lib --example cube
```
No keys — the cube spins on its own.
---
## `pbr` — PBR Metallic/Roughness + Normal Mapping
Demonstrates the Cook-Torrance PBR workflow: GGX distribution + Smith geometry +
Schlick Fresnel + hemispheric IBL + normal mapping.
```sh
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,
cave, textured floor). The floor is a 20×20 plane with the `ground.jpeg`
albedo; the cave cube pairs `cave.jpg` (albedo) with `caveNormal.jpg`
(normal map, pre-encoded sRGB before upload — see the *Texture assets* section
in the parent README) and shows real surface detail under the light.
---
## `import` — OBJ File Import
**Non-graphical** example: parses a `.obj` file and prints statistics
(vertex count, normals, UVs, indices, bounding box) to stdout.
```sh
# 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.
---
## `manual` — Low-level Workflow (no `App` facade)
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:
- `Context` (*Manager* layer): GPU lifecycle — `Instance`/`Surface`/`Adapter`/
`Device`/`Queue`, `configure()` for the swapchain, per-frame surface texture.
- `Renderer` (*Executor* layer): `render(view, mesh, material)` = one object per
submission; `present(frame)`.
- `PipelineCache`: `register_shader(id, path)` then `Material::new(format, id, &mut cache)`.
The window and GPU are created in winit 0.30's `resumed()` callback
(`run_app` + `ApplicationHandler`). The two-layer architecture is detailed in
[`docs/tech/ARCHI_APP.md`](../../../docs/tech/ARCHI_APP.md) and
[`FRAME_LOOP.md`](../../../docs/tech/FRAME_LOOP.md).
```sh
cargo run -p wsg-lib --example manual
```
No keys — static render (unlit quad, 4 colors).
> **Tip**: start with the declarative workflow. The manual workflow doesn't
> render more pixels — it gives more control over command encoding.