GPU Rendering Demo

PBR scene rendered with wgpu featuring shadows, MSAA, and metallic-roughness materials.

The GPU demo renders a physically-based scene using aether-renderer's wgpu backend. It demonstrates real-time shadow mapping, 4x MSAA, and PBR materials with independent metallic and roughness parameters -- all running in a resizable winit window.

What It Demonstrates

  • wgpu rendering pipeline with a shadow pass followed by a forward PBR pass, both managed by GpuRenderer.
  • PBR materials using a metallic-roughness workflow. The scene includes a grey floor, red and blue cubes, and metallic and matte spheres -- each with distinct albedo, roughness, and metallic values.
  • Shadow mapping from a directional light source, rendered into a depth texture and sampled during the forward pass.
  • 4x MSAA for edge anti-aliasing, configured automatically by the renderer.
  • Camera controls with six degrees of freedom -- translate with WASD and vertical movement with Space/Shift, rotate with arrow keys.

How to Run

cargo run -p gpu-demo

The window defaults to 1280x720. You can override the size with environment variables:

AETHER_WINDOW_WIDTH=1920 AETHER_WINDOW_HEIGHT=1080 cargo run -p gpu-demo

Controls

KeyAction
W / A / S / DMove camera forward / left / backward / right
Arrow keysRotate camera (yaw and pitch)
SpaceMove camera up
ShiftMove camera down
ESCQuit

Subsystems Showcased

CrateRole in this demo
aether-rendererGpuRenderer, PBR material system, shadow pass, MSAA configuration

Key Code Walkthrough

Scene setup (scene.rs) uploads geometry and materials to the GPU via the renderer. Five PBR materials are defined with different properties:

floor: PbrMaterial::new(floor_id)
    .with_albedo(0.4, 0.4, 0.4, 1.0)
    .with_roughness(0.9)
    .with_metallic(0.0),
red_cube: PbrMaterial::new(red_id)
    .with_albedo(0.9, 0.15, 0.1, 1.0)
    .with_roughness(0.4)
    .with_metallic(0.1),

The floor is a subdivided plane (8x8), cubes and spheres use built-in geometry generators from geometry.rs, and each object gets a SceneObject struct that maps its mesh, material, and model-uniform index.

Application loop (main.rs) uses winit's ApplicationHandler trait. On resumed, it creates the wgpu instance, surface, and GpuRenderer. Each RedrawRequested event:

  1. Computes delta time from the previous frame.
  2. Applies keyboard input to the camera (translation and rotation).
  3. Uploads updated camera and model uniforms to the GPU.
  4. Builds a list of DrawCommand structs from the scene objects.
  5. Calls renderer.render(&commands) which executes the shadow and forward passes.

Camera (camera.rs) stores position, yaw, pitch, and derives a view matrix plus projection matrix. The to_uniforms() method packs these into the struct expected by the GPU shaders.

Source Location

All source files live under examples/gpu-demo/src/:

  • main.rs -- entry point, winit event loop, input handling
  • scene.rs -- geometry uploads, PBR material definitions, draw commands
  • camera.rs -- camera state, view/projection matrix generation
  • geometry.rs -- procedural mesh builders (plane, cube, sphere)