83daeb4c7dc9f6a395c54e703efe7251125d2a91
WSG — WGPU Simple Graphics Library
WSG (WGPU Simple Graphics) is a Rust library that wraps wgpu and winit to draw 3D without touching wgpu directly.
What you get
- A 3D window in ~30 lines — no wgpu, no winit in your code
- Phong lighting (directional, point, spot) + shadows (shadow mapping)
- HDR + Tone Mapping (ACES Filmic / Reinhard) — opt-in, zero cost when disabled
- GPU-driven pipeline — world matrices + frustum culling on the GPU, indirect draws
- LOD (Level of Detail) — automatic geometry degradation based on distance
- Procedural primitives — cube, sphere, cylinder, cone, torus, plane
- File import — built-in OBJ parser (glTF in progress)
- Orbital camera + unified input (keyboard/mouse)
- LOD, culling, HDR, shadows: everything is opt-in — what you don't enable costs nothing
Strengths
| Strength | Detail |
|---|---|
| Zero wgpu in your code | The declarative API (AppBuilder + AppHandler) encapsulates everything |
| Opt-in = zero cost | A disabled effect allocates nothing, executes nothing |
| Cargo features | Only compile the primitives/importers you need |
| One shader | The standard shader (Phong) covers 90% of cases; unlit mode for 2D |
| GPU-driven | CPU sends transforms, GPU does the rest (matrices, culling, draws) |
Quickstart
use wsg_lib::prelude::*;
use wsg_lib::app::AppBuilder;
use wsg_lib::utils::WsgError;
struct MyScene;
impl AppHandler for MyScene {
fn setup(&mut self, app: &mut wsg_lib::App) {
app.scene
.register_shader("standard", wsg_lib::utils::STANDARD_SHADER_PATH)
.unwrap();
app.scene
.create_material("mat", "standard", None)
.unwrap();
// A Phong-lit cube, sitting on a ground plane
app.scene
.create_mesh("cube", cube(1.0), Some("mat"))
.unwrap();
app.scene
.add_entity("my_cube", "cube")
.unwrap();
app.scene
.create_mesh("ground", plane(10.0, 10.0, 1, 1), Some("mat"))
.unwrap();
app.scene
.add_entity("floor", "ground")
.unwrap();
}
}
fn main() -> Result<(), WsgError> {
let mut app = AppBuilder::new()
.title("My WSG scene")
.with_hdr(ToneMapper::Aces) // optional: HDR + tone mapping
.build()?;
app.run(MyScene);
Ok(())
}
[dependencies]
wsg-lib = { path = "../lib" }
pollster = { version = "1", features = ["macro"] }
cargo run --example demo # full showcase (6 primitives, 3 lights, shadows, HDR)
Features
| Category | What's available |
|---|---|
| Geometry | 6 procedural primitives + OBJ import + custom Geometry |
| Rendering | Phong (lit), unlit (2D flat), PBR metallic/roughness, HDR + tone mapping |
| Lights | Directional, point, spot (8 max) + ambient |
| Shadows | Shadow mapping (directional/spot), slope-scaled bias, PCF |
| LOD | Auto quadric decimation, hysteresis, 1 buffer multi-level |
| GPU-driven | Compute pass (matrices + culling) → indirect draws |
| Post-process | Bloom, Depth of Field, Fog (3 modes), MSAA 4× |
| Camera | Orbital (drag/zoom/reset) + presets (front/side/top) |
| Input | Keyboard (pressed/held/released), mouse (delta, scroll, buttons) |
| Textures | RGBA8 (from bytes, from file, white placeholder) |
Documentation
| Where | What |
|---|---|
| docs/user/ | User guide — how to use the API, step by step |
| docs/tech/ | Internal architecture — decisions, specs, targets |
| docs/ROADMAP.md | Roadmap (phases 1-5 ✅, phase 6 in progress) |
| docs/PLAN.md | Recipe book (step history) |
cargo doc -p wsg-lib --no-deps |
API reference (rustdoc, 100% covered) |
Examples
| Example | What it shows |
|---|---|
demo |
Full showcase: 6 primitives, 3 lights, shadows, HDR, LOD, orbital camera |
bloom |
HDR bloom post-process |
hdr |
HDR + tone mapping (ACES/Reinhard) |
emissive |
Emissive materials + runtime exposure control |
shadow |
Shadow mapping in isolation |
culling |
GPU-driven frustum culling (15×15 grid) |
msaa |
4× multisample anti-aliasing |
fog |
3 fog modes (linear, exponential, exponential²) |
dof |
Depth of field with focus presets |
pbr |
PBR metallic/roughness + normal mapping |
import |
OBJ file import (feature import-obj) |
manual |
Low-level workflow (Context/Renderer/PipelineCache, no App) |
Cargo Features
# Default: all primitives
wsg-lib = { path = "../lib" }
# Minimal: just the cube
wsg-lib = { path = "../lib", default-features = false, features = ["prim-cube"] }
# With OBJ import
wsg-lib = { path = "../lib", features = ["import-obj"] }
| Feature | Enables |
|---|---|
prim-cube, prim-plane, prim-sphere, prim-cylinder, prim-cone, prim-torus |
Primitives |
all-prims (default) |
All 6 primitives |
import-obj |
Wavefront OBJ parser |
import-gltf |
glTF (stub) |
Build
cargo build --workspace # everything
cargo test --workspace # 127 tests
cargo check --all-targets # quick check
cargo run -p wsg-lib --example demo # run the showcase
Project
- Language: Rust 2024
- Dependencies: wgpu 30, winit 0.30, glam (math)
- Not published on crates.io (path dependency)
- Status: MVP complete (phases 1-5 ✅), post-MVP in progress (phase 6)
Detailed documentation (architecture, status, API reference, manual workflow): README_DETAILS.md
This project was heavily developed using OpenCode, Pi Code, and JCode AI agents running on local Qwen3-27b_Q4 and DeepSeek V4 Flash Q4 instances. The project organization and architecture are the author's own design.
Description
Languages
Rust
93%
WGSL
7%