update demos et docs
This commit is contained in:
@@ -9,12 +9,12 @@ cargo run -p wsg-lib --example <name>
|
||||
|
||||
| Example | Command | Description |
|
||||
|---------|---------|-------------|
|
||||
| `demo` | `cargo run -p wsg-lib --example demo` | **Showcase** (Step 15): one of each primitive, procedural textures, directional + point + spot lights, a shadow-casting light, and a live orbital camera (drag / wheel zoom / `R` reset / `1`-`3` presets). |
|
||||
| `demo` | `cargo run -p wsg-lib --example demo` | **Showcase**: one of each primitive, procedural textures, directional + point + spot lights, a shadow-casting light, and a live orbital camera (drag / wheel zoom / `R` reset / `1`-`3` presets). |
|
||||
| `simple` | `cargo run -p wsg-lib --example simple` | Flat unlit quad (minimal declarative workflow, `AppBuilder` + auto scene). |
|
||||
| `cube` | `cargo run -p wsg-lib --example cube` | Textured cube (procedural checker) lit by a directional + point + spot light. |
|
||||
| `manual` | `cargo run -p wsg-lib --example manual` | Low-level workflow: `Context`, `Renderer`, `PipelineCache`, `Mesh` used directly (no `App` facade). |
|
||||
| `spot_test` | `cargo run -p wsg-lib --example spot_test` | Spot-light isolation: only one spot is on (near-zero ambient), cube rotates on two axes so the oriented beam is clearly visible. |
|
||||
| `shadow_test` | `cargo run -p wsg-lib --example shadow_test` | Shadow mapping (Step 14): one directional light is the shadow caster (`set_shadow_caster(Some(0))`); a cube casts a PCF-softened shadow onto a thin ground slab. |
|
||||
| `shadow_test` | `cargo run -p wsg-lib --example shadow_test` | Shadow mapping: one directional light is the shadow caster (`set_shadow_caster(Some(0))`); a cube casts a PCF-softened shadow onto a thin ground slab. |
|
||||
|
||||
## Conventions
|
||||
|
||||
|
||||
+10
-10
@@ -1,11 +1,11 @@
|
||||
//! Step 5 — MVP 3D: a lit unit cube that rotates; **Step 10** — the cube is **textured**
|
||||
//! (procedural checkerboard) via the new diffuse path (bind group `@group(2)`).
|
||||
//! A lit unit cube that rotates, **textured** with a procedural checkerboard via the diffuse path
|
||||
//! (bind group `@group(2)`).
|
||||
//!
|
||||
//! Demonstrates the MVP goal of ROADMAP 1.3 + 1.5: a 3D mesh with Phong lighting on screen.
|
||||
//! A 3D mesh with Phong lighting on screen — the library's 3D showcase.
|
||||
//! Follows the declarative workflow (like `simple`): `AppBuilder` + automatic scene, **no wgpu import**.
|
||||
//! Since Step 7 the scene owns its `PipelineCache`: go through `register_shader` +
|
||||
//! `add_material_shader`/`add_material_texture` + `create_mesh` + `add_entity`. Since Step 8 the mesh
|
||||
//! is declared from a **`Geometry`** (positions, normals, indices). Since Step 10 (D4) a texture is
|
||||
//! The scene owns its `PipelineCache`: go through `register_shader` +
|
||||
//! `add_material_shader`/`add_material_texture` + `create_mesh` + `add_entity`. The mesh
|
||||
//! is declared from a **`Geometry`** (positions, normals, indices). A texture is
|
||||
//! registered by id (`add_texture`) and a textured material bound to it (`add_material_texture`);
|
||||
//! the texture is generated *procedurally* (RGBA 8×8 checkerboard) to stay self-contained, no on-disk asset.
|
||||
//! The default active camera (`Scene::default`, position (0,0,3), fov 45°) frames the cube, and
|
||||
@@ -24,7 +24,7 @@ struct Cube {
|
||||
}
|
||||
|
||||
/// Generates a *procedural* RGBA 8×8 checkerboard (white/brick), no on-disk asset, to texture the
|
||||
/// cube (Step 10, D3/D4). Returned as a raw RGBA8 `Vec<u8>`, loadable via `Texture::from_rgba8`.
|
||||
/// cube. Returned as a raw RGBA8 `Vec<u8>`, loadable via `Texture::from_rgba8`.
|
||||
fn checkerboard_rgba() -> Vec<u8> {
|
||||
const SIZE: u32 = 8;
|
||||
let mut rgba = Vec::with_capacity((SIZE * SIZE * 4) as usize);
|
||||
@@ -40,7 +40,7 @@ fn checkerboard_rgba() -> Vec<u8> {
|
||||
|
||||
impl AppHandler for Cube {
|
||||
fn setup(&mut self, app: &mut wsg_lib::App) {
|
||||
// Phong shader `standard` (carries the frame + object + texture bind groups, Step 10).
|
||||
// Phong shader `standard` (carries the frame + object + texture bind groups).
|
||||
app.scene
|
||||
.register_shader("standard", wsg_lib::utils::STANDARD_SHADER_PATH)
|
||||
.unwrap();
|
||||
@@ -63,7 +63,7 @@ impl AppHandler for Cube {
|
||||
.unwrap();
|
||||
app.scene.add_entity("cube", "cube_mesh").unwrap();
|
||||
|
||||
// Step 12 (Phase 4.2): in addition to the default directional light (+Z), a warm **point** light
|
||||
// In addition to the default directional light (+Z), a warm **point** light
|
||||
// is added in front of the cube. Its halo (linear attenuation over the
|
||||
// radius) is visible on the near face of the cube, on top of the directional lighting.
|
||||
app.scene
|
||||
@@ -75,7 +75,7 @@ impl AppHandler for Cube {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Step 13 (Phase 4.2): a green **spot** light aimed at the cube from the left.
|
||||
// A green **spot** light aimed at the cube from the left.
|
||||
// The cone (half-angle ~20°) projects a directed beam onto the cube's faces, with a
|
||||
// smoothed penumbra at the edge and linear attenuation over the radius.
|
||||
app.scene
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! **WSG `demo`** — the final showcase example (Step 15, sous-volt 15.C).
|
||||
//! **WSG `demo`** — the final showcase example.
|
||||
//!
|
||||
//! Combines everything built throughout the library into one declarative scene:
|
||||
//!
|
||||
@@ -6,7 +6,7 @@
|
||||
//! (`cube`, `uv_sphere`, `icosphere`, `cylinder`, `cone`, `torus`) placed around it,
|
||||
//! * a **procedural texture** per mesh (checker / stripe grids, no assets on disk),
|
||||
//! * the **standard** Phong material wired to those textures,
|
||||
//! * an **orbital camera** driven live by the unified input state (Step 15.B):
|
||||
//! * 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),
|
||||
//! * `R` resets the view, keys `1`/`2`/`3` jump to front / side / top presets,
|
||||
//! * a **directional** light (the shadow caster) + a **point** light + a **spot** light,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
//! Low-level workflow: direct use of `Context`, `Renderer`, `PipelineCache`, `Mesh` and
|
||||
//! `Material`, bypassing the `App` facade. Renders a flat quad (shader `standard` **unlit**) via the
|
||||
//! winit 0.30 loop (`EventLoop::run_app` + `ApplicationHandler`). The window and the GPU are created
|
||||
//! in `resumed()`, as required by winit 0.30 and the migration done in `app.rs`. Since Step 8
|
||||
//! (DRAFT 8.5) the mesh is built via `Mesh::from_geometry(device, Arc<Geometry>, None)` from
|
||||
//! a `Geometry` (positions + colors per vertex) instead of `Mesh::new(device, &[Vertex], ..)`.
|
||||
//! in `resumed()` (winit 0.30 only exposes the display after resume). The mesh is built via
|
||||
//! `Mesh::from_geometry(device, Arc<Geometry>, None)` from a `Geometry` (positions + colors per vertex).
|
||||
use std::sync::Arc;
|
||||
use winit::application::ApplicationHandler;
|
||||
use winit::dpi::LogicalSize;
|
||||
@@ -70,9 +69,9 @@ impl ApplicationHandler for App {
|
||||
// 3. Material: uses renderer.device() and renderer.format()
|
||||
let material = Material::new(renderer.format(), "standard", &mut cache);
|
||||
|
||||
// Mesh: uses the renderer's device. Since Step 8 the mesh is built from a
|
||||
// `Geometry` (positions + colors per vertex) via `Mesh::from_geometry` — the mesh also keeps
|
||||
// the `Arc<Geometry>` on the CPU side (retention D5).
|
||||
// Mesh: uses the renderer's device. The mesh is built from a `Geometry`
|
||||
// (positions + colors per vertex) via `Mesh::from_geometry` — the mesh also keeps the
|
||||
// `Arc<Geometry>` on the CPU side.
|
||||
let geometry = Geometry::new(vec![
|
||||
// Position (x,y,z) | Color (r,g,b,a) — normals/UVs default via to_vertices
|
||||
[-0.5, 0.5, 0.0],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Dedicated test for **shadow mapping** (Step 14, Phase 4.2).
|
||||
//! Dedicated test for **shadow mapping**.
|
||||
//!
|
||||
//! A single **directional** light is configured as the shadow caster
|
||||
//! (`Scene::set_shadow_caster(Some(0))`). The cube sits on a large thin ground
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
//! Minimal declarative workflow, no explicit WGPU handling in this file.
|
||||
//! `AppBuilder` creates the event loop, then `App::run` opens the window, builds the `Context`/`Renderer`
|
||||
//! and drives the update → render → present loop. Since the winit 0.30 migration, the GPU only exists
|
||||
//! and drives the update → render → present loop. In winit 0.30 the GPU only exists
|
||||
//! after `resumed`: that is why shader registration + mesh/material/entity creation live in
|
||||
//! the `AppHandler::setup` hook, called once the context is ready. Since Step 7 the PipelineCache
|
||||
//! the `AppHandler::setup` hook, called once the context is ready. The PipelineCache
|
||||
//! lives in the scene (`Scene::init_gpu`, called in `resumed`): go through `register_shader` +
|
||||
//! `add_material_shader` + `create_mesh` + `add_entity`, the material being bound to the mesh. Since Step 8
|
||||
//! (DRAFT 8.4/8.5) the mesh is declared from a **`Geometry`**: per-vertex positions + colors
|
||||
//! `add_material_shader` + `create_mesh` + `add_entity`, the material being bound to the mesh. The mesh
|
||||
//! is declared from a **`Geometry`**: per-vertex positions + colors
|
||||
//! for the unlit quad. The scene renders automatically: the default `render()` method calls
|
||||
//! `app.render_scene(frame.view())`.
|
||||
use wsg_lib::AppHandler;
|
||||
@@ -40,7 +40,7 @@ impl AppHandler for MonQuad {
|
||||
.with_indices(vec![0, 1, 2, 0, 2, 3]);
|
||||
|
||||
// Default material: `None` lets the Scene inject its `standard` at render time
|
||||
// (`Scene::default_material`, DRAFT Step 7.3.5) — this exercises the default path.
|
||||
// (`Scene::default_material`) — this exercises the default path.
|
||||
app.scene.create_mesh("quad_mesh", geometry, None).unwrap();
|
||||
app.scene.add_entity("quad", "quad_mesh").unwrap();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Test dedicated to **spot lights** (Step 13, Phase 4.2).
|
||||
//! Test dedicated to **spot lights**.
|
||||
//!
|
||||
//! In this example, **only** a spot light is on (the default directional light is
|
||||
//! removed via `clear_lights()`) and the ambient is deliberately **very low**. The cube therefore
|
||||
|
||||
+1
-2
@@ -26,8 +26,7 @@ use crate::core::Frame;
|
||||
pub trait AppHandler {
|
||||
/// Called once by `App::run`, right after the window/GPU context are created (winit `resumed`).
|
||||
/// Use it to register shaders, build Meshes/Materials, and populate `app.scene` before the loop
|
||||
/// starts. This replaces the pre-`run` setup that was possible before the winit 0.30 migration.
|
||||
/// Default implementation does nothing.
|
||||
/// starts. Default implementation does nothing.
|
||||
/// Inputs: app — mutable reference to the fully-initialized App facade.
|
||||
fn setup(&mut self, _app: &mut App) {}
|
||||
/// Called once per frame before rendering begins. Used for physics updates, input processing,
|
||||
|
||||
@@ -6,9 +6,8 @@ Contains WGSL shader source files used by the PipelineCache module. These are lo
|
||||
disk when referenced by their registered ID in PipelineCache.register_shader(). If a file is missing,
|
||||
PipelineCache falls back to the embedded STANDARD_SHADER constant defined in utils::conf.
|
||||
|
||||
Since Step 5, only **one shader** remains: `standard_shader.wgsl` (Phong). The former
|
||||
`basic_shader.wgsl` was removed as a separate pipeline — flat 2D rendering is now the **unlit
|
||||
variant** of `standard` (decision ratified in the DRAFT: "2D ⊂ 3D").
|
||||
The directory contains a **single shader**: `standard_shader.wgsl` (Phong). Flat 2D rendering is
|
||||
the **unlit variant** of `standard`.
|
||||
|
||||
## Files
|
||||
|
||||
@@ -21,7 +20,7 @@ variant** of `standard` (decision ratified in the DRAFT: "2D ⊂ 3D").
|
||||
`standard_shader.wgsl` is WSG's unified (Phong) shader. It exposes the two bind groups shared
|
||||
by every material (Step 3: a single layout for all).
|
||||
|
||||
### Vertex Input Layout (56-byte stride — correspond au `resources::Vertex`)
|
||||
### Vertex Input Layout (56-byte stride — matches `resources::Vertex`)
|
||||
|
||||
| Location | Attribute | Type | Offset (bytes) |
|
||||
|----------|-----------|------|----------------|
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
//! - **app::AppBuilder** reads APP_DEFAULT_TITLE, APP_DEFAULT_WIDTH, and APP_DEFAULT_HEIGHT for default window configuration.
|
||||
|
||||
/// Path to the standard (Phong) WGSL shader file on disk (runtime). Used by PipelineCache::load_shader()
|
||||
/// for file-based loading. This is the unified pipeline shader (Step 3: a single layout for all):
|
||||
/// for file-based loading. This is the unified pipeline shader (a single layout for all):
|
||||
/// it carries the full uniform contract (frame + object bind groups) and supports an unlit mode so flat
|
||||
/// 2D rendering is a special case of the 3D lit path. The `basic` family was removed (Step 5).
|
||||
/// 2D rendering is a special case of the 3D lit path.
|
||||
///
|
||||
/// NOTE: the shipped `assets/shaders/*.wgsl` files are OPTIONAL — when they are absent (library consumed
|
||||
/// from a checkout without the assets directory, or from a published crate), `PipelineCache::load_shader`
|
||||
|
||||
Reference in New Issue
Block a user