Rendering Architecture
Purpose and Scope
This document provides an architectural overview of Three.js's rendering subsystems, covering how scenes are transformed from scene graph representations to pixels on screen. The rendering architecture encompasses both WebGL and WebGPU backends, shader program management, state caching, and resource coordination.
For detailed information about specific subsystems:
- Render loop and frame execution: see WebGL Rendering Pipeline
- Shader compilation and management: see Shader Programs & ShaderLib
- WebGL state and resource caching: see State & Resource Management
- Shadow rendering passes: see Shadow Mapping
- WebGPU backend and node materials: see WebGPU & Node Materials
For scene graph structure and object hierarchy: see Scene Graph & Object3D
Renderer Architecture Overview
Three.js provides two primary rendering backends implemented as separate classes. The WebGLRenderer class (used since r163, WebGL 2 only) serves as the primary production renderer, while the WebGPU renderer represents the next-generation graphics API support.
High-Level Renderer Structure
Rendering Subsystem Organization
The WebGLRenderer delegates specialized tasks to modular subsystems, each managing a specific aspect of the rendering pipeline.
| Subsystem | Primary Class | Responsibility |
|---|---|---|
| Shader Management | WebGLPrograms | Program selection, compilation, caching |
| State Caching | WebGLState | GL state change tracking, deduplication |
| Geometry Upload | WebGLGeometries | VBO creation, attribute binding |
| Texture Management | WebGLTextures | Texture upload, parameter caching |
| Render Coordination | WebGLRenderLists | Object sorting (opaque/transparent) |
| Lighting Setup | WebGLRenderStates | Per-scene light accumulation |
| Shadow Rendering | WebGLShadowMap | Shadow map generation, filtering |
| Capability Detection | WebGLCapabilities | GPU limits, extension availability |
| Resource Tracking | WebGLInfo | Draw call counts, memory stats |
Frame Rendering Flow
The rendering process follows a well-defined sequence from scene traversal to final pixel output. The WebGLRenderer.render() method orchestrates this multi-stage pipeline.
Render Method Execution Flow
Shader Program Pipeline
Shader programs are the compiled GPU code that transforms vertices and computes fragment colors. The WebGLPrograms subsystem manages program selection, compilation, and caching based on material properties and scene context.
Program Selection and Compilation Flow
Built-in Shader Library
The ShaderLib provides template shaders for all standard material types. Each entry contains uniform definitions, vertex shader source, and fragment shader source. These shaders are composed from reusable ShaderChunk modules.
ShaderLib Material Types
| ShaderLib Key | Material Type | Lighting Model |
|---|---|---|
| basic | MeshBasicMaterial | Unlit |
| lambert | MeshLambertMaterial | Lambertian diffuse |
| phong | MeshPhongMaterial | Blinn-Phong specular |
| standard | MeshStandardMaterial | PBR (metallic/roughness) |
| physical | MeshPhysicalMaterial | PBR + clearcoat/transmission |
| toon | MeshToonMaterial | Cel-shaded |
| matcap | MeshMatcapMaterial | Matcap texture |
| points | PointsMaterial | Point sprites |
| dashed | LineDashedMaterial | Dashed lines |
| depth | MeshDepthMaterial | Depth encoding |
| normal | MeshNormalMaterial | Normal visualization |
| distance | MeshDistanceMaterial | Distance from point |
Shader Composition with ShaderChunk
State Management and Caching
The WebGLState class wraps all WebGL state-changing calls to minimize redundant GPU commands. It tracks the current state and only issues GL calls when the desired state differs from the cached state.
Cached State Categories
Resource Upload and Caching
Geometry and texture data must be uploaded to GPU memory before rendering. The renderer maintains separate subsystems for managing these resources with intelligent caching.
Resource Management Subsystems
| Class | Upload Target | Cache Strategy |
|---|---|---|
| WebGLAttributes | Vertex Buffer Objects (VBOs) | By BufferAttribute.uuid |
| WebGLGeometries | Complete geometries | By BufferGeometry.id + attribute versions |
| WebGLTextures | Texture data | By Texture.id + source version + parameters |
| WebGLRenderTarget | Framebuffer Objects (FBOs) | By render target instance |
| WebGLCubeMaps | Cube environment maps | By texture instance with PMREMGenerator |
| WebGLCubeUVMaps | CubeUV environment maps | By texture instance, managed lifetime |
Texture Upload Flow
Render Lists and Sorting
Before rendering, the scene graph must be traversed to build lists of renderable objects. The WebGLRenderLists system organizes objects into opaque and transparent groups, then sorts them for correct rendering order.
Render List Population
Sorting Strategy
| Object Type | Primary Sort | Secondary Sort | Direction |
|---|---|---|---|
| Opaque | renderOrder then material.id | z (depth) | Front to back (optimization) |
| Transparent | renderOrder | z (depth) | Back to front (correctness) |
Transparent objects must render back-to-front for correct alpha blending. Opaque objects render front-to-back to leverage early depth testing and reduce overdraw.
Backend Comparison: WebGL vs WebGPU
Three.js supports two rendering backends with different architectures. The WebGL backend is mature and production-ready, while WebGPU represents next-generation GPU APIs with compute shader support.
Architectural Differences
| Aspect | WebGLRenderer | WebGPU Renderer |
|---|---|---|
| API Version | WebGL 2.0 only (since r163) | WebGPU (Chrome 113+) |
| Shader Language | GLSL ES 3.0 | WGSL |
| Material System | Traditional properties | Node-based materials (TSL) |
| State Management | Global state machine (cached) | Command encoders (stateless) |
| Compute Shaders | Not supported | Fully supported |
| Build Output | three.module.js | three.webgpu.js, three.tsl.js |
| Coordinate System | Y-up, right-handed | Configurable |
WebGPU Architecture (briefly, detailed in WebGPU & Node Materials)
The WebGPU backend uses a fundamentally different approach:
- Node materials: Material properties defined via node graphs instead of simple properties
- Render bundles: Pre-recorded command sequences for repeated draws
- Compute passes: GPU compute shaders for physics, particles, post-processing
- Multiple render targets: Native support for rendering to multiple textures simultaneously
Initialization and Context Creation
The renderer must acquire a WebGL context and initialize all subsystems before rendering can begin. This process includes capability detection, extension loading, and subsystem instantiation.
Renderer Initialization Sequence
Context Attributes
The renderer requests a WebGL2 context with specific attributes defined at construction:
// From WebGLRenderer constructor
const contextAttributes = {
alpha: true,
depth: true,
stencil: false,
antialias: false,
premultipliedAlpha: true,
preserveDrawingBuffer: false,
powerPreference: 'default',
failIfMajorPerformanceCaveat: false,
};Material-to-Shader Mapping
Different material types require different shader programs. The WebGLPrograms system analyzes material properties and scene context to generate appropriate shader code.
Material Type to ShaderLib Mapping
Shader Variant Generation
For each material type, hundreds of shader variants may be generated based on:
- Texture usage (map, normalMap, roughnessMap, etc.)
- Lighting configuration (number and type of lights)
- Feature flags (fog, shadows, morphTargets, skinning)
- Material properties (transparency, double-sided, etc.)
Example parameter combination for MeshStandardMaterial:
// Generated in WebGLPrograms.getParameters()
{
map: true,
normalMap: true,
roughnessMap: true,
metalnessMap: true,
envMap: true,
lights: true,
shadowMapEnabled: true,
numDirLights: 2,
numPointLights: 3,
// ... many more parameters
}Each unique combination results in a different compiled shader program.
Render Target System
Render targets allow rendering to off-screen textures instead of the canvas. This enables multi-pass rendering, post-processing effects, shadow maps, and environment map generation.
WebGLRenderTarget Structure
A render target consists of:
- One or more color textures (attachments)
- Optional depth buffer (renderbuffer or texture)
- Optional stencil buffer
- Dimensions and pixel format specifications
Render Target Usage Pattern
Common Render Target Applications
| Use Case | Configuration | Consumer |
|---|---|---|
| Shadow Maps | Depth texture, single channel | WebGLShadowMap generates, materials sample |
| Post-processing | RGBA color texture | Effects read previous frame output |
| Reflection Maps | Cube render target (6 faces) | Environment mapping on materials |
| Picking | Integer format for object IDs | Mouse interaction / selection |
| Multisampling | MSAA samples > 1 | Antialiasing without postprocess |
Performance Monitoring
The WebGLInfo object tracks rendering statistics useful for performance analysis and debugging. It counts draw calls, geometry uploads, texture uploads, and shader compilations.
WebGLInfo Statistics
// Accessed via renderer.info
{
memory: {
geometries: 42, // Number of BufferGeometries uploaded
textures: 18 // Number of Textures on GPU
},
render: {
calls: 156, // Number of draw calls this frame
triangles: 84320, // Total triangles rendered
points: 0,
lines: 0,
frame: 0 // Frame counter
},
programs: [...] // Array of compiled WebGLPrograms
}By monitoring render.calls and render.triangles, developers can identify performance bottlenecks. High draw call counts suggest excessive scene fragmentation, while high triangle counts indicate geometry complexity.
Summary
The Three.js rendering architecture is organized into modular subsystems that collaborate to transform scene graphs into rendered pixels:
- WebGLRenderer orchestrates the overall rendering process and owns all subsystems
- WebGLPrograms manages shader selection, compilation, and caching based on material/scene parameters
- WebGLState wraps GL state changes to minimize redundant GPU commands
- WebGLGeometries and WebGLTextures handle resource upload and caching
- WebGLRenderLists organize objects for efficient rendering with proper sorting
- WebGLRenderStates accumulate lighting information per scene/camera
- WebGLShadowMap implements shadow mapping via depth-only render passes
This architecture enables high-performance rendering while maintaining flexibility for diverse material types and rendering techniques. The caching and state management layers ensure minimal GPU overhead even in complex scenes.
For implementation details of each subsystem, see the child pages: WebGL Rendering Pipeline, Shader Programs & ShaderLib, State & Resource Management, Shadow Mapping, and WebGPU & Node Materials.