Rendering Architecture
Overview
SiliconGhetto’s rendering layer (sg_render) is built on wgpu and targets WebGPU with automatic WebGL2 fallback. All rendering goes through a unified pipeline that works identically in the browser (via WASM) and on native targets (for development and testing).
GPU Initialization
Browser Canvas → wgpu Instance → Surface → Adapter → Device + Queue
- Instance: Created with
Backends::all()to support WebGPU and WebGL2 - Surface: Created from a canvas element (or OffscreenCanvas in worker mode)
- Adapter: Selected based on power preference (high performance by default)
- Device + Queue: The primary interface for all GPU operations
The GpuContext struct in sg_render::gpu owns the device, queue, and surface configuration.
2D Sprite Rendering
The sprite renderer uses instanced quad rendering:
Per-sprite data (instance buffer):
┌──────────────────────────────────────┐
│ position (vec2) │ size (vec2) │
│ color (vec4) │ uv_offset (vec2) │
└──────────────────────────────────────┘
Vertex shader:
1. Read per-vertex quad position (4 vertices)
2. Scale by instance size
3. Translate by instance position
4. Transform by view-projection uniform
Fragment shader:
1. Sample texture (or use solid color)
2. Multiply by instance color
3. Output final color
SpriteBatch
SpriteBatch collects draw calls each frame and uploads them as a single instance buffer:
batch.begin();
for (transform, sprite) in query.iter(&world) {
batch.draw_quad(transform.position, size, sprite.color);
}
batch.upload(&device); // Single buffer upload
batch.draw(&render_pass); // Single draw call
This batches hundreds or thousands of sprites into one GPU draw call.
3D Rendering
The 3D pipeline adds:
- Depth buffer: 32-bit float depth texture for correct occlusion
- Camera: Perspective projection with orbit controls
- Lighting: Directional light with diffuse shading (Blinn-Phong)
- Vertex format: Position, normal, color (extensible to UV, tangent)
3D Pipeline Setup
Vertex Buffer → Vertex Shader → Rasterizer → Fragment Shader → Depth Test → Output
↑ ↑
View-Projection Light Direction
Uniform Uniform
Camera System
Camera2D
Orthographic projection for 2D rendering:
- Origin at top-left (screen coordinates)
- View-projection matrix maps pixel coordinates to clip space
- Supports panning and zoom
Camera3D (scene3d demo)
Perspective projection for 3D rendering:
- Configurable FOV, near/far planes
- Orbit camera: rotates around a target point
- View matrix from eye position, target, and up vector
Shader Architecture
All shaders are written in WGSL (WebGPU Shading Language):
crates/sg_render/ → shared pipeline utilities
demos/sprite-lab/ → sprite.wgsl (instanced 2D quads)
demos/scene3d/ → scene3d.wgsl (lit 3D geometry)
Shaders are included at compile time via include_str!() and compiled to GPU shader modules at runtime.
Render Pass Structure
Each frame executes one render pass:
Begin Render Pass (clear color + depth)
├─ Set pipeline
├─ Set bind groups (uniforms)
├─ Set vertex/index buffers
├─ Draw (instanced for sprites, indexed for meshes)
└─ End render pass
Submit command buffer
Present surface texture
Future frames may use multiple render passes for effects like post-processing or shadow maps.
Performance Considerations
- Batching: Sprites are batched to minimize draw calls
- Buffer reuse: Instance buffers are pre-allocated and reused each frame
- Minimal state changes: Pipeline and bind group switches are minimized
- WebGL2 fallback: Some features (compute shaders, storage textures) are unavailable on WebGL2; the engine detects capabilities at init time