Core Concepts
Before we write code, let's understand the high-level concepts that make this project work.
1. WGPU
wgpu is the Rust library we use to talk to the GPU. It is built on the WebGPU standard, which is the successor to WebGL. Unlike OpenGL (state machine) or Vulkan (too verbose), WebGPU strikes a balance between performance and safety.
WebGPU runs on DirectX 12 on Windows, Metal on macOS, and Vulkan on Linux/Android. You write code once, and wgpu translates it.
2. Compute Shaders
Most graphics tutorials teach Vertex and Fragment shaders (how to draw triangles and pixels). Compute Shaders are different. They are general-purpose programs that run on the GPU. They don't output pixels; they modify data in memory.
In our particle system:
- Compute Shader: Calculates physics (position += velocity * time) for millions of particles.
- Vertex Shader: Transforms 3D positions to 2D screen coordinates.
- Fragment Shader: Colors the pixels.
3. WGSL (WebGPU Shading Language)
Shaders are written in a special language called WGSL. It looks a bit like Rust but runs on the GPU. We will write two shader files:
compute_shader.wgsl: The physics engine.draw_shader.wgsl: The renderer.
4. GPU Buffers
Data needs to move from CPU RAM to GPU VRAM. We use Buffers for this.
- Uniform Buffer: Small data sent every frame (e.g., Camera Matrix, Time, Mouse Position). Read-only for shaders.
- Storage Buffer: Large data arrays (e.g., Particle Positions). Can be read and written by compute shaders.
5. Data Flow Diagram
Here is how data moves in a single frame:
CPU (Rust)
│
├── 1. Update Uniforms (Time, Camera, Mouse)
│ │
│ ▼
│ [GPU Uniform Buffer]
│
└── 2. Dispatch Compute Pass
│
▼
[GPU Compute Shader] ◄── Read/Write ──► [Particle Storage Buffer]
│ │
│ (Wait for compute to finish) │
▼ │
[GPU Draw Pass] ◄────── Read Only ────────────┘
│
▼
[Screen / Canvas]
6. WebAssembly (WASM)
WASM is a binary instruction format for a stack-based virtual machine. It allows code written in languages like C, C++, and Rust to run on the web at near-native speed. We use wasm-bindgen to bridge Rust and JavaScript.