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
+33 -6
View File
@@ -4,7 +4,8 @@
//!
//! * a **ground plane** plus one of each procedural primitive from `math::primitives`
//! (`cube`, `uv_sphere`, `icosphere`, `cylinder`, `cone`, `torus`) placed around it,
//! * a **procedural texture** per mesh (checker / stripe grids, no assets on disk),
//! * **textures per mesh**: the ground is a **file asset** (`ground.jpeg`) and the cube a
//! **UV atlas asset** (`uv_texture.jpg`), the rest stay procedural (checker / stripe grids),
//! * the **standard** Phong material wired to those textures,
//! * an **orbital camera** driven live by the unified input state:
//! hold the **left mouse button** and drag to orbit (yaw/pitch), the wheel zooms (distance),
@@ -43,6 +44,9 @@ use wsg_lib::camera::CameraController;
use wsg_lib::resources::Texture;
use wsg_lib::utils::WsgError;
/// Texture asset directory, resolved against the crate root so the example works from any CWD.
const TEXTURES: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/examples/assets/textures");
/// Generates an 8×8 RGBA checkerboard (white / brick) as raw bytes for `Texture::from_rgba8`.
fn checkerboard_rgba() -> Vec<u8> {
const SIZE: u32 = 8;
@@ -109,13 +113,36 @@ impl AppHandler for Demo {
(ctx.device.clone(), ctx.queue.clone())
};
// 2. Procedural textures, one material per pattern.
// 2. Textures: two **file assets** (ground + UV atlas) plus two procedural patterns.
// File paths are resolved against the crate root (`CARGO_MANIFEST_DIR`) so the
// example works from any CWD.
let ground_tex = Texture::from_file(
&device,
&queue,
"ground",
&format!("{TEXTURES}/ground.jpeg"),
)
.unwrap();
app.scene.add_texture("ground_texture", ground_tex).unwrap();
app.scene
.add_material_texture("ground_mat", "standard", "ground_texture")
.unwrap();
let uv_tex = Texture::from_file(
&device,
&queue,
"uv_atlas",
&format!("{TEXTURES}/uv_texture.jpg"),
)
.unwrap();
app.scene.add_texture("uv_texture", uv_tex).unwrap();
app.scene
.add_material_texture("uv_mat", "standard", "uv_texture")
.unwrap();
let checker =
Texture::from_rgba8(&device, &queue, 8, 8, &checkerboard_rgba(), "checker").unwrap();
app.scene.add_texture("checker_texture", checker).unwrap();
app.scene
.add_material_texture("ground_mat", "standard", "checker_texture")
.unwrap();
app.scene
.add_material_texture("solid_mat", "standard", "checker_texture")
.unwrap();
@@ -140,7 +167,7 @@ impl AppHandler for Demo {
// packed into the mesh's single vertex/index buffers (D7). Zooming with the wheel
// switches levels on the fly (asymmetric hysteresis, D4).
app.scene
.create_mesh("cube_mesh", cube(0.8), Some("solid_mat"))
.create_mesh("cube_mesh", cube(0.8), Some("uv_mat"))
.unwrap();
app.scene
.create_mesh_with_lod(