Core Idea
Projection is the third of the three MVP matrices — the one that carries camera space into clip space — and it is the pipeline’s lens. There are exactly two families. Flip the scene above between them: perspective makes the colonnade converge toward the fog, because rays meet at the eye; orthographic holds every column the same size no matter how far, because rays travel parallel.
| Perspective | Orthographic | |
|---|---|---|
| View volume | frustum (truncated pyramid) | box |
| Parallel lines | converge | stay parallel |
w in clip space |
carries depth | always 1 |
| Feels like | the world | a blueprint |
Why Distance Shrinks Things
There is no trick — only similar triangles. Rays from an object’s ends converge at the eye; where they pierce the image plane is the image:
image size = height · near / depth
Drag one bar to exactly twice the other’s depth: half the image. The perspective matrix implements this by copying the vertex’s depth into w; the perspective divide (x/w, y/w, z/w) that follows does the shrinking. The orthographic matrix writes w = 1, the divide does nothing, and depth is ignored — which is why it’s the lens for CAD, isometric views, and UI overlays where sizes must be trusted.
The Dolly Zoom
The two lenses are not different kinds of thing — they are two ends of one dial. In the demo above, switch on dolly zoom and drag the fov: the camera backs away exactly as the lens narrows, keeping distance · tan(fov/2) constant. The subject holds still while the space behind it flattens — the vertigo shot. Push it to the limit (camera infinitely far, fov infinitely narrow) and perspective becomes orthographic. That’s also how the morph between modes works: the ortho box is sized to match the frustum at the subject’s plane, so the two matrices agree there and disagree everywhere else.
Four Numbers
A perspective camera is fully defined by fov (vertical, in degrees), aspect, near and far; an orthographic one by its box bounds:
new THREE.PerspectiveCamera(fov, aspect, near, far)
new THREE.OrthographicCamera(left, right, top, bottom, near, far)
Near and far are not cosmetic — they bound the depth buffer’s precision. Keep near as large as the scene allows and far as small: a tiny near plane is how z-fighting is made (clip space has the interactive proof).
Not Really a Matrix
A 4×4 matrix cannot divide, so perspective projection is not an affine transformation — no matrix alone can do it. The matrix only stages the division: it places camera-space depth into w (the second job of homogeneous coordinates), writes gl_Position, and the GPU performs ÷w in hardware after the vertex shader ends. Equivalently: perspective = a squish that deforms the frustum into a box, followed by an orthographic projection of that box. The projection matrix encodes the squish; the hardware finishes it.
Connections
Projection is the last hop of the coordinate-space journey before clip space, where the −w ≤ x,y,z ≤ w test and the divide happen. Its parameters live in a matrix only because homogeneous coordinates give w a place to exist — and the near/far pair chosen here decides how much depth precision the rest of the pipeline gets to spend.