Intro to Three.js
You just wrote 40 lines of boilerplate to draw a pink triangle. Compiling shaders, linking programs, managing buffers, wiring attributes — that's the reality of raw WebGL. Three.js wraps all of that into a clean, high-level API. Scenes, cameras, geometry, materials, lights — the concepts you'd expect from a 3D engine. Same GPU underneath, vastly less pain on top.
Why Three.js?
Here's the same coloured triangle from the previous lesson. Raw WebGL on the left, Three.js on the right:
Three.js is the most popular WebGL library — used in product configurators, data visualisations, games, creative coding, and basically every “cool 3D website” you've seen. It handles shader compilation, buffer management, matrix maths, lighting calculations, and much more. You focus on what to build, not how the GPU works.
In our playground, THREE is provided as a variable automatically — no import needed. You also have canvas, animate(), and onCleanup() as before.
Scene, Camera, Renderer
Every Three.js app needs three things. A Scene — the container for all your 3D objects. A Camera — defines what you're looking at and how perspective works. And a WebGLRenderer — takes the scene and camera and draws the result onto a canvas.
MeshBasicMaterial ignores lighting — it just shows the flat colour. That's why the cube looks like a solid block. Try changing camera.position.z — smaller values zoom in, larger values zoom out. Change the rotation values to see different faces.
Geometry + Material = Mesh
Three.js has built-in geometry for common shapes: BoxGeometry, SphereGeometry, ConeGeometry, TorusGeometry, and more. Pair any geometry with a material, wrap them in a Mesh, and add it to the scene. That's it.
Each shape is a few lines. Try changing the geometry parameters — the numbers control size, segments, and detail. SphereGeometry(0.7, 8, 8) gives a low-poly sphere. TorusGeometry(0.5, 0.2, 16, 48) — first two numbers control the ring and tube radii. Can you add a CylinderGeometry?
Lighting
MeshBasicMaterial ignores light entirely — useful for flat colours, but it makes everything look 2D. Switch to MeshStandardMaterial and suddenly lighting matters. Without any lights, everything is black. Add an AmbientLight for a soft base, and a DirectionalLight for a sun-like source that gives surfaces depth and shadow.
Now the sphere looks round — the light gives it shading. Try moving the sun: sun.position.set(-3, 4, 2) lights from the other side. Change the ambient light intensity — set it to 0 and only the directional light remains, creating dramatic shadows. Try adding a PointLight: new THREE.PointLight(0xf1c40f, 2, 10) at a specific position.
Animation
Same concept as the 2D animation lesson: use the animate() helper to run a function every frame. The difference is that instead of clearing and redrawing the canvas yourself, you call renderer.render(scene, camera) and Three.js handles everything. Rotate objects via mesh.rotation.x += 0.01.
A spinning lit cube in about 25 lines. Change the rotation speed, or make it spin on only one axis. Try scaling: cube.scale.x = 1 + 0.3 * Math.sin(timestamp * 0.002) makes it pulse. Can you add a second shape orbiting the cube using Math.sin / Math.cos on its position?
Putting it all together
Let's build something that would have been hundreds of lines in raw WebGL: a mini solar system with orbiting spheres, a glowing central star, and smooth camera motion. Every technique here — scenes, geometry, materials, lighting, animation — is something you've already seen.
A solar system in ~60 lines. Add more planets to the array — adjust dist, speed, and size. Try adding a moon: create a small sphere and orbit it around one of the planets instead of the centre. Change scene.background to a lighter colour, or try new THREE.FogExp2(0x0a0a1a, 0.1) for atmospheric depth. Can you make the star change colour over time?