Core Idea
Every vertex travels the same chain, and each hop is entered by a matrix — step through it above and watch one gold vertex’s numbers change at every stop:
| Space | What it’s for | Exit |
|---|---|---|
| Local | the object’s own shape, centred on its origin | × Model matrix |
| World | all objects share one scene | × View matrix |
| Camera | the world as the camera sees it (camera at origin, looking down −Z) | × Projection matrix |
| Clip | gl_Position — 4D; visible if −w ≤ x, y, z ≤ w |
÷ w (automatic) |
| NDC | everything visible fits [−1, 1]³, hardware-independent |
viewport mapping |
| Screen | pixel coordinates | — |
In the vertex shader the three matrices compose into one — MVP:
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
A Matrix Doesn’t Move Anything
Multiplying by the model matrix doesn’t move the object — it re-expresses the same point in a different frame. The geometry in the vertex buffer never changes; “motion” is just a new matrix each frame, a flipbook of reference frames over static drawings. Feel it directly — the point below never moves, only its numbers do:
This is also why a bare vector like (3, 2, 0) means nothing on its own — it’s only meaningful relative to a frame. Mixing spaces (a world-space light against an object-space normal) produces valid arithmetic and geometric nonsense: the most common shader bug there is. Always know which space a vector is in.
The Camera Paradox
There is no camera at the hardware level — only the View matrix, the inverse of the camera’s transform. Moving the camera forward is mathematically the whole world moving backward; in camera space the camera sits at (0,0,0) by definition. Step to Camera in the journey above and watch it happen: the world swings, the camera doesn’t.
Space Hopping
The practical skill is choosing the cheapest space for the question:
| Computation | Best space |
|---|---|
| Object shape, collision geometry | Local |
| Placing objects, physics | World |
| Lighting (camera is a known point) | Camera |
| Mouse click → 3D ray | unproject Screen → World |
| Shadow mapping | the light’s own camera space |
Two staples built from hops: raycasting runs the pipeline backwards (screen click through inverse projection and view → a world-space ray), and shadow maps render the scene from the light’s point of view — the light is a camera.
Hierarchy: Spaces All the Way Down
A scene graph is a transform hierarchy — every node’s world matrix is its parent’s times its own:
M_world = M_parent_world × M_local
Move a parent and every child follows through one chain of matrix multiplications. Beyond the pipeline chain there’s also per-surface tangent space (normal, tangent, bitangent — the TBN frame used in normal mapping): the same idea at the smallest scale — a coordinate frame wherever it’s convenient.
Connections
Each hop is a matrix multiplication whose columns are the target frame’s basis vectors; homogeneous coordinates (w = 1) are what let translation join in. The model matrix decomposes into TRS — see transformations. The projection step has its own page (projection), and the strangest stop on the journey — clip space — deserves its own too.