004761252b
- weld: Δ UV = 0.5 exact n'est plus soudé (ambigu: fente à sa plus large vs saut légitime — la colonne u=1 du cône vs le chart disque du cap tombait exactement dessus et mélangeait les charts) - collapse: les UV se blendent linéairement. Le fold par coordonnée (Δ entier → 0) figeait l'UV du sommet sur les vertices de base (bande de rayures, signalée par l'utilisateur) — il était inutile: les jumeaux de fente sont gelés, aucun repli ne traverse la fente - welded renvoie un struct Welded (clippy) - test cône: dual-chart (fan latéral bilinéaire + disque du cap), surface latérale r = λ; test seam/span réécrit selon la sémantique finale - doc: gpu-driven.md, ARCHI_CPU_GPU.md (box LOD), DRAFT.md (D10) alignés sur la sémantique finale (gel des jumeaux, blend linéaire, seuil strict) - AGENTS.md: gotcha 'ne jamais folder un saut entier de tuile' 102 tests passent, demo lance et rend sans erreur.
55 lines
3.5 KiB
Markdown
55 lines
3.5 KiB
Markdown
# WSG - WGPU Simple Graphics Library
|
|
|
|
## Project Type
|
|
Rust workspace (2024 edition) wrapping [wgpu](https://github.com/gfx-rs/wgpu) for simple 3D drawing operations.
|
|
|
|
## Workspace Structure
|
|
```
|
|
Cargo.toml # workspace root — no dependencies here
|
|
lib/Cargo.toml # wsg-lib crate: wgpu 30.0.0, winit 0.30
|
|
examples/Cargo.toml # depends on wsg-lib via path reference
|
|
lib/lib.rs # lib entry point
|
|
lib/context.rs # Context type (aggregates wgpu objects: Instance, Surface, Adapter, Device, Queue)
|
|
lib/renderer.rs # renderer implementation
|
|
examples/src/main.rs # example binary
|
|
```
|
|
|
|
**Key convention**: `wsg-lib` is referenced from `examples/` via relative path (`path = "../lib"`). Do not publish this to crates.io as-is — it uses a local path dependency.
|
|
|
|
## Essential Commands
|
|
| Action | Command |
|
|
|--------|---------|
|
|
| Build everything | `cargo build --workspace` |
|
|
| Run examples | `cargo run -p examples` |
|
|
| Test | `cargo test --workspace` |
|
|
| Check | `cargo check --workspace` |
|
|
| Format | `cargo fmt --all` |
|
|
|
|
No custom scripts or linting tooling beyond standard Cargo conventions.
|
|
|
|
## Architecture Overview
|
|
The library's purpose is to abstract the five core wgpu objects into a single **Context**:
|
|
|
|
- **Instance** — GPU backend selection (Vulkan/Metal/DX12)
|
|
- **Surface** — window rendering surface (via winit)
|
|
- **Adapter** — physical/logical GPU device
|
|
- **Device** — buffer/texture/pipeline creation
|
|
- **Queue** — command submission
|
|
|
|
WGPU doesn't have a native "Context" object — this type groups them together for a simpler user API. See README.md for the French documentation of each component.
|
|
|
|
## Gotchas
|
|
- Rust 2024 edition is used. Ensure your Rust toolchain supports it (`rustup update`).
|
|
- wgpu 30.0.0 is pinned in `lib/Cargo.toml`. The comment says "check the latest version" — verify compatibility before upgrading.
|
|
- No feature flags, no dev-dependencies, no tests yet. Adding any requires updating both `Cargo.toml` files if the dependency spans crates.
|
|
- The workspace has no `[workspace.dependencies]` section. Dependencies are declared per-crate rather than centrally.
|
|
- **WGSL `select` argument order** (cost us a day): `select(reject, accept, cond)` returns the **second** arg when `cond` is true — the reverse of HLSL's `select(trueVal, falseVal, cond)`. In `shaders/gpu_driven.wgsl` the cull pass must stay `select(0u, u32(flags.z), visible)` (visible ⇒ full count, culled ⇒ 0). Swapped args silently zero the counts of every visible entity → black window. See the GOTCHA comment at the top of that shader.
|
|
- **LOD UV blending: never fold integer-tile jumps, freeze seam twins instead** (cost us a day, 2026-09-23): a UV *seam* is two copies of the same 3-D point on integer-apart UVs (u=0/u=1 columns) — it is NOT a mesh edge, so the decimation must record the weld's refused pairs and **freeze** those twins (any edge touching one is excluded from the PQ). A co-facial edge spanning a whole tile (cone apex v=1 ↔ base v=0) is a *legit* chart span — the chart is bilinear, so the UVs **blend linearly** (fold the integer jump to zero and the apex UV smears down the cone side). And the attribute-aware weld refuses a Δ of *exactly* 0.5 (ambiguous: seam at its widest vs legit half-tile jump — the cone's u=1 column vs the cap-disc chart sits exactly there). See the comments in `geometry.rs` (`welded`, `Collapse::collapse_edge`) and the cone/seam regression tests.
|
|
|
|
<!-- lean-ctx -->
|
|
## lean-ctx
|
|
|
|
Prefer lean-ctx MCP tools over native equivalents for token savings.
|
|
Full rules: @LEAN-CTX.md
|
|
<!-- /lean-ctx -->
|