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
  1. Instance: Created with Backends::all() to support WebGPU and WebGL2
  2. Surface: Created from a canvas element (or OffscreenCanvas in worker mode)
  3. Adapter: Selected based on power preference (high performance by default)
  4. 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