Scene to Screen
Scene, camera, renderer
Lesson 1 of 5
What you'll learn
- Stand up the minimal Three.js trio: Scene, PerspectiveCamera, WebGLRenderer
- Understand what fov, aspect, near, and far actually control
- See that rendering is one explicit function call — and that perspective is just a divide by z
Every Three.js app — a product configurator, a game, a data visualization — begins with the same three objects. A Scene is a container: you add() things to it. A PerspectiveCamera defines a point of view and a viewing volume. A WebGLRenderer owns a <canvas> and knows how to draw the scene from the camera's point of view.
import * as THREE from "three";
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
60, // fov: vertical field of view, in degrees
window.innerWidth / window.innerHeight, // aspect: canvas width / height
0.1, // near: closer than this is clipped
100 // far: farther than this is clipped
);
camera.position.z = 5;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.render(scene, camera); // draw exactly one frame
The four camera arguments describe a frustum — a truncated pyramid of visible space. fov is how wide the pyramid opens vertically; aspect matches it to the canvas shape so nothing stretches; near and far are the front and back clipping planes. Anything outside the frustum is never drawn.
Rendering is one function call
renderer.render(scene, camera) draws one frame into the canvas and returns. Nothing loops, nothing watches for changes. If you move the camera afterwards, the pixels don't update until you call render again — the animation loop in lesson 4 is just this call repeated.
Don't set near to 0.0001
The depth buffer's precision is spread between near and far, and most of it is spent close to the near plane. A tiny near value makes distant surfaces z-fight (flicker). Keep near as large as your scene allows.
Under all the matrices, perspective projection is one move: divide x and y by distance. Far things get divided by a bigger z, so they land closer to the center of the screen — that's foreshortening. The challenge builds it from scratch: project two identical cubes onto a character-grid "screen" and print the frame.
Run it. Two identical cubes are projected onto an ASCII screen by dividing x and y by z. The far cube comes out smaller — that IS perspective. Try moving the far cube closer (change 14 to 8) and re-run.
What does calling renderer.render(scene, camera) actually do?
Next: an empty scene renders a black rectangle — time to put a mesh in it, and learn why some materials need lights.
Saved on this device. Sign in to sync your progress everywhere.