Three.js

Three.js is the standard library for 3D graphics in the browser. It wraps WebGL (and increasingly WebGPU) — the low-level GPU API that is powerful but brutally verbose — in an approachable scene-graph model: create a scene, add objects with geometry and materials, point a camera at it, and render. Product configurators, data visualizations, portfolio showpieces, interactive maps, and browser games all run on it.

Raw WebGL requires hundreds of lines of shader code and buffer management to draw a single spinning cube. Three.js makes that cube a dozen lines while keeping the full power accessible when you need it. It's the connective tissue between "I know JavaScript" and "I can put interactive 3D on a web page."

TL;DR

Quick Example

A lit, rotating cube — the "hello world" of WebGL, in Three.js:

Core Concepts

The Scene Graph

Three.js organizes everything as a tree of objects with positions, rotations, and scales — parent transforms cascade to children (rotate a car group, its wheels come along). The renderer walks this graph each frame and draws it from the camera's viewpoint.

Meshes: Geometry + Material

Every visible object is a Mesh combining:

The gotcha every beginner hits: a MeshStandardMaterial scene with no lights renders pure black. PBR materials need illumination.

Loading Real Models and Textures

Primitives get you started; real 3D content comes from artists as glTF (the web-standard 3D format — "the JPEG of 3D"):

Textures (image files mapped onto surfaces), environment maps (for reflections), and skeletal animations all load similarly. OrbitControls adds click-drag camera movement in one line.

The Render Loop and Interaction

3D is real-time: requestAnimationFrame calls your loop each frame (~60fps), where you update object states and re-render. Delta-time (clock.getDelta()) keeps motion frame-rate independent. Clicking objects uses raycasting — projecting a ray from the camera through the cursor to find what it hits.

WebGL, WebGPU, and Shaders

Under Three.js sits WebGL (OpenGL ES in the browser); the emerging WebGPU backend brings modern GPU features and better performance, and Three.js's node-material system targets both. At the bottom are shaders — GLSL programs running on the GPU per-vertex and per-pixel — which power every custom visual effect. You can go far without writing shaders; mastering them is where browser 3D becomes a specialty.

Performance: The Central Discipline

Browser 3D lives or dies on frame rate, and the levers are specific:

Mobile is the real test: a scene that flies on a desktop GPU can hit 15fps on a mid-range phone.

React Three Fiber and the Ecosystem

In React apps, imperative Three.js code fights React's model. React Three Fiber (R3F) reconciles them — Three.js objects become JSX components:

Same Three.js underneath, but declarative, composable, and integrated with React state. The drei helper library adds cameras, controls, loaders, and effects as ready components. For most React-based 3D work, R3F is the default entry point. Beyond it: Babylon.js (a heavier, more game-engine-like alternative) and PlayCanvas occupy the fuller-engine end.

Common Mistakes

Black Screen (No Lights)

The rite of passage: a MeshStandardMaterial scene with no light source renders black. Add an AmbientLight and a DirectionalLight, or use MeshBasicMaterial for unlit content.

Not Disposing GPU Resources

Removing a mesh from the scene doesn't free its GPU memory — geometries, materials, and textures must be explicitly .dispose()d. In a long-running app (or one that loads many models), leaked buffers accumulate into crashes.

Ignoring Mobile

Desktop GPUs hide sins. Test on real mid-range phones early; the draw-call, polygon, and texture budgets that feel generous on a laptop are tight on mobile.

Fighting React with Imperative Three.js

Wiring raw Three.js into a React component (manual refs, effects, cleanup) is painful and bug-prone. If you're in React, use React Three Fiber — it exists precisely to make this pleasant.

Skipping the Math

Coordinates, transforms, cameras, and lighting are real concepts; treating Three.js as a black box leads to "why is my object off-screen / inside-out / invisible" flailing. A little vector/matrix intuition saves hours.

FAQ

Do I need to know graphics/math to use Three.js?

Basic 3D concepts (coordinates, cameras, transforms, lighting) — yes, and Three.js is a great way to learn them. Deep linear algebra and shader (GLSL) programming — only for advanced custom visuals. You can build product configurators and data viz with the high-level API and light math.

Three.js or a game engine like Unity?

Three.js targets the web — it ships as part of a web page, integrates with your DOM/React UI, and needs no plugin or download. Unity/Godot target richer games with full editors and physics but export heavier web builds. For web-embedded 3D (configurators, viz, marketing, casual games), Three.js; for a serious 3D game, a game engine.

What's the difference between WebGL and WebGPU here?

WebGL is the mature, universally-supported GPU API Three.js has always used; WebGPU is the modern successor with better performance and compute capabilities, now supported by Three.js's newer backend. You can largely ignore the distinction and let Three.js pick — WebGPU where available, WebGL fallback.

How do I get 3D models into a scene?

Export/obtain them as glTF/GLB (the web standard) and load with GLTFLoader. Artists produce these in Blender/Maya; marketplaces and libraries (Sketchfab, Poly Haven) provide ready assets. glTF carries geometry, PBR materials, and animations together.

Is it hard to get good performance?

It requires attention, not genius. The rules are known and specific (minimize draw calls, budget polygons and textures, dispose resources, cap pixel ratio, instance repeated objects) — apply them and 60fps is very achievable, including on mobile. Ignoring them is how "3D is slow" myths start.

Related Topics

References