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)
This commit is contained in:
Jérôme Bousquié
2026-09-26 10:49:13 +02:00
parent fecfdcd2d2
commit e5f3636b42
32 changed files with 341 additions and 104 deletions
+26 -2
View File
@@ -57,7 +57,8 @@ Four constructors:
| `Texture::from_file(device, queue, label, path)` | image file on disk |
| `Texture::white_placeholder(device, queue)` | 1×1 white — used internally when a material has no texture |
You get `device`/`queue` in `setup()` via `app.context()`:
You get `device`/`queue` in `setup()` via `app.context()` (clone them out of the
borrow before touching `app.scene` again — see the pattern in every textured example):
```rust
let (device, queue) = {
@@ -70,7 +71,30 @@ app.scene.add_material_texture("ground_mat", "standard", "checker_texture").unwr
```
The exact snippet (8×8 checkerboard + stripes generation) is in
[`demo.rs`](../../../lib/examples/effects/demo.rs) and [`cube.rs`](../../../lib/examples/meshes/cube.rs).
[`demo.rs`](../../../lib/examples/effects/demo.rs).
For **file textures** (the pattern used by `cube`, `demo`, `shadow`, `fog`, `dof`,
`culling` and `pbr`), load from `assets/textures/` and resolve the path against
`CARGO_MANIFEST_DIR` so the example works from any working directory:
```rust
const TEXTURES: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/examples/assets/textures");
let texture = Texture::from_file(
&device,
&queue,
"uv_atlas",
&format!("{TEXTURES}/uv_texture.jpg"),
)
.unwrap();
```
The sampler is `Linear` + `Repeat`, so textures tile automatically when UVs exceed
[0,1] (e.g. the 80×80 fog floor tiles `ground.jpeg`).
> **Normal maps**: `Texture` is always `Rgba8UnormSrgb`, so the GPU sRGB-decodes on
> sample. A normal map is *linear* data — pre-encode its channels with the sRGB OETF
> before upload so the round-trip is the identity. See `load_normal_map` in
> [`pbr.rs`](../../../lib/examples/meshes/pbr.rs).
Two conditions for a texture to show up:
1. the material is created via `add_material_texture` (otherwise the 1×1 white placeholder