Three.js Architecture Overview
How a 3D scene flows from JavaScript objects to GPU pixels — tracing the data path through every major subsystem.
What Three.js Is
Three.js is a scene graph abstraction over WebGL. It manages the full pipeline from high-level objects (meshes, lights, cameras) down to raw GPU draw calls, shader compilation, and buffer uploads.
The entry-point pattern from the README:
import * as THREE from 'three';
// Scene graph
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(70, width / height, 0.01, 10);
camera.position.z = 1;
// Geometry + Material → Mesh
const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
const material = new THREE.MeshNormalMaterial();
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// Renderer: orchestrates the whole pipeline
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
renderer.setAnimationLoop(animate);
document.body.appendChild(renderer.domElement);
function animate(time) {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
renderer.render(scene, camera); // ← everything happens here
}
Every call to renderer.render(scene, camera) triggers the full pipeline described in this documentation.
Architecture Map
The major subsystems and their relationships:
USER CODE
scene.add(mesh) renderer.render(scene, camera)
│ │
▼ ▼
SCENE GRAPH WEBGL RENDERER
Scene │
└─ Object3D (hierarchy) ├─ 1. updateMatrixWorld() ← scene traversal + matrix calc
├─ Mesh ├─ 2. projectObject() ← visibility / frustum cull
│ ├─ BufferGeometry ├─ 3. RenderList.sort() ← opaque front→back, transparent back→front
│ └─ Material ├─ 4. shadowMap.render() ← depth pass for shadows
├─ Light ├─ 5. renderScene() ← opaque → transmissive → transparent
└─ Camera │ └─ renderObject()
│ ├─ getProgram() ← compile/cache GLSL shaders
│ ├─ setUniforms() ← lights, textures, matrices
GPU │ └─ bindingStates.setup() ← VAO, attribute pointers
WebGL Context ←────────────── └─ 6. gl.drawElements() ← actual GPU draw call
Shader Program
Vertex Buffer (VBO)
Index Buffer (IBO)
Vertex Array Object (VAO)
Framebuffer / Texture
Data Flow: Step by Step
1
Scene Graph Construction
User creates
Scene, Mesh (geometry + material), and Camera. scene.add(mesh) sets parent/child links in the Object3D tree. No GPU work yet — this is all JavaScript object management.2
Matrix Hierarchy Update
scene.updateMatrixWorld() walks the tree depth-first, composing each node's local transform (position × rotation × scale) into a world-space matrixWorld. The camera also gets a matrixWorldInverse (the view matrix) and projectionMatrix.3
Scene Traversal & Culling
projectObject() walks the scene graph recursively. Each Mesh is checked against the camera frustum and layer mask. Visible objects are pushed into a RenderList categorized as opaque, transmissive, or transparent, with their clip-space Z depth recorded.4
Render List Sorting
Opaque objects sort front-to-back (Z ascending) to maximize early Z-rejection on the GPU. Transparent objects sort back-to-front (Z descending) so alpha blending composites correctly. Within each group, objects sort by material ID to reduce GPU state changes.
5
Shadow Pass
For each shadow-casting light, the scene is rendered from the light's perspective into a depth texture (shadow map). Later, the main render samples this texture to determine which fragments are in shadow.
6
Shader Program Compilation & Caching
getProgram() computes a cache key from the material type, light configuration, fog, skinning, and other state. If no cached program exists, it compiles GLSL vertex and fragment shaders from built-in chunks, links them, and stores the result.7
Uniform Upload & Vertex Binding
Per-draw uniforms (model/view/projection matrices, material color, textures, light data) are written to the GPU. Vertex attributes (position, normal, UV) are bound via a Vertex Array Object (VAO) that maps BufferAttribute arrays to shader attribute slots.
8
GPU Draw Call
gl.drawElements() (indexed) or gl.drawArrays() (non-indexed) fires. The vertex shader runs per vertex, the rasterizer interpolates, and the fragment shader runs per pixel. Output goes to the canvas (or a render target for post-processing).Component Pages
Scene Graph
src/scenes/Scene.js · src/core/Object3D.js
How objects are organized in a hierarchy, how transforms compose from local to world space, and how the tree is built and modified.
Geometry
src/core/BufferGeometry.js · BufferAttribute.js
How vertex data (positions, normals, UVs) is stored in typed arrays, uploaded to GPU buffers, and indexed for triangle connectivity.
Material & Shader
src/materials/Material.js · WebGLPrograms.js
How materials define appearance, how GLSL shaders are compiled and cached, and how uniforms (lights, textures, matrices) reach the GPU.
Camera
src/cameras/PerspectiveCamera.js
How view and projection matrices are computed, how the frustum is derived for culling, and how the camera fits into the scene graph.
Renderer Pipeline
src/renderers/WebGLRenderer.js
The full orchestration: scene traversal, render list, sorting, shadow pass, draw calls, and how every subsystem connects here.
Key Concepts & External References
Scene Graph
- Wikipedia — Scene Graph — tree data structure for spatial organization of objects
- OpenGL Tutorial — Matrices — how model/view/projection transforms work
- Three.js Docs — Object3D — official API reference
Rendering Pipeline
- WebGL Fundamentals — How it Works — vertex/fragment shader pipeline explained visually
- Khronos — Rendering Pipeline Overview — authoritative GPU pipeline reference
- MDN — WebGL Best Practices — state changes, batching, draw call costs
Math
- Euclidean Space — Quaternion to Matrix — how rotation is stored and composed
- Wikipedia — Viewing Frustum — the volume used for frustum culling
- Scratchapixel — Projection Matrix — math behind perspective projection
Transparency & Sorting
- LearnOpenGL — Blending — why transparent objects must sort back-to-front
- NVIDIA — Depth Precision — near/far plane impact on Z-buffer precision
Source Code Entry Points
All links are permalinks to commit d59cf621.
- src/Three.js — main module export
- src/core/Object3D.js — base class for all scene objects
- src/scenes/Scene.js — scene container
- src/core/BufferGeometry.js — vertex data container
- src/materials/Material.js — material base class
- src/cameras/PerspectiveCamera.js — perspective projection
- src/renderers/WebGLRenderer.js — main renderer (3700+ lines)
- src/renderers/webgl/WebGLAnimation.js — animation loop