Files
Greg Shuflin 24efbeddf2 Initial claude-generated commit
prompt:

yeah give me a starter project structure with rust + wgpu + trunk, with
a really simple 3d scene - maybe just moving the camera around 3d space
with WSAD, and a couple of flat-shaded colorful spheres and octohedrons
floating in space to give something to look at
2026-02-07 20:54:13 -08:00

1.7 KiB

wgpu-demo

A minimal 3D tech demo using Rust + wgpu + winit, compiled to WASM via Trunk.

Flat-shaded colorful spheres and octahedra floating in space. WASD + mouse to fly around.

Prerequisites

# Install trunk (WASM bundler)
cargo install trunk

# Add the WASM target
rustup target add wasm32-unknown-unknown

Run in browser (WASM)

trunk serve

Then open http://127.0.0.1:8080 — click to capture the mouse, WASD to move, mouse to look, Space/Shift for up/down, Escape to release cursor.

Run natively (desktop)

cargo run --release

Same controls. Native build uses Vulkan/Metal/DX12 via wgpu.

Deploy

trunk build --release

This produces a dist/ folder you can deploy to any static host (Vercel, Netlify, GitHub Pages, etc).

Project structure

src/
  main.rs       — Entry point, winit event loop, input handling, WASM bootstrap
  renderer.rs   — wgpu device/surface/pipeline setup, render loop
  camera.rs     — FPS camera with mouse look
  mesh.rs       — Procedural icosphere + octahedron generation (flat-shaded)
  scene.rs      — Scene population: random placement of colored shapes
  shader.wgsl   — Vertex + fragment shader with directional + specular lighting

Notes

  • The renderer writes per-object model transforms via queue.write_buffer each draw call. This is fine for ~30 objects but you'd want instanced rendering or a dynamic uniform buffer for hundreds+.
  • web-time is used instead of std::time::Instant because the latter panics on WASM.
  • On WASM, wgpu uses WebGPU if available, falling back to WebGL2 via the GL backend.
  • Binary size: release builds with opt-level = "s" + LTO are typically 1-3 MB gzipped.