BuildBot

Scene to Screen

The scene graph and transforms

Lesson 3 of 5

What you'll learn

  • Parent objects with add() and reason about the resulting tree
  • Distinguish local position/rotation/scale from world-space transforms
  • See how matrix multiplication propagates a parent's transform to every descendant

Nearly everything you put in a scene — meshes, lights, cameras, empty Groups — extends Object3D, and parent.add(child) links them into a tree: the scene graph. The payoff is that an object's position, rotation (an Euler, in radians), and scale are local — expressed relative to its parent. Move the parent, and every descendant comes along for free.

const earthOrbit = new THREE.Object3D(); // an invisible pivot
scene.add(earthOrbit);

const earth = new THREE.Mesh(earthGeometry, earthMaterial);
earth.position.x = 10;      // 10 units from the SUN, not from the world origin
earthOrbit.add(earth);

const moon = new THREE.Mesh(moonGeometry, moonMaterial);
moon.position.x = 3;        // 3 units from the EARTH
earth.add(moon);

earthOrbit.rotation.y += 0.01; // one line orbits the earth AND drags the moon along

Local vs world space

earth.position reads (10, 0, 0) forever — that's its local position. Where the earth actually is in the world depends on every ancestor. During render, Three.js walks the tree and computes each object's matrixWorld as the parent's matrixWorld times the object's local matrix (built from position, rotation, scale). That single multiplication rule is the scene graph.

When you need world coordinates — for a camera target, a raycast, or physics — ask for them:

const worldPos = new THREE.Vector3();
moon.getWorldPosition(worldPos); // forces a matrixWorld update, then extracts position

Scale propagates too

A parent's scale multiplies into every descendant — including distances. Put a moon 3 units from an earth inside a parent scaled by 2, and the moon sits 6 world-units out. Non-uniform parent scale plus child rotation produces skew; keep scales on leaf meshes when you can.

The challenge is a miniature scene graph in 2D: nodes with local position/rotation/scale, matrices multiplied parent-into-child, world positions printed as a tree. One rotation on a pivot moves everything under it.

Matrix propagation through a scene graph

Run it. earth's LOCAL x is always 10, but its WORLD position depends on its ancestors: rotating earthOrbit a quarter turn swings earth (and the moon riding on it) around the sun. Try rotation = Math.PI for a half turn.

Loading editor…
Knowledge check

Where does an Object3D's position property place it?

Next: a scene that never changes only needs one render — animation is re-rendering on a loop, with delta time keeping the speed honest.

Saved on this device. Sign in to sync your progress everywhere.