Skip to content
Giovani Drosda Lima
Maths · Graphics

A simple formula that demystifies 3D graphics

·

You can draw "three-dimensional" graphics on a two-dimensional plane by playing with perspective. Software that gives an impression of depth does it with tricks that fool human perception, and one very simple formula is enough to pull it off:

x' = x / z
y' = y / z

The two-dimensional Cartesian plane

Picture a two-dimensional plane: width and height, nothing else. For coordinates, put the point (0, 0) in the middle. At the centre of the plane, x and y are both zero.

Hand-drawn Cartesian plane, with the x axis horizontal and the y axis vertical, both marked from -3 to 3 and crossing at the origin.
The two-dimensional Cartesian plane

That is what the x and y in the formula stand for: the position of a point on a Cartesian plane. (3, 3) would be a point in the top right of this image, (-3, 0) a point on the left at mid height, and (0, -3) a point at the bottom, in the centre.

The three-dimensional Cartesian plane

z is simply one more axis on the graph: depth, running from front to back. Here, the larger the z, the further back the point is.

The x, y and z axes drawn in perspective, with an observer in the foreground looking along the z axis (labelled "observador", Portuguese for observer).
The z axis gives depth, measured from the observer

If z grows the further back a point is, it follows that:

  • the further back, the larger the denominator, and
  • the larger the denominator, the smaller the result.

This matches the real world. Look out of a window and imagine a point in the top right corner. Now imagine the point keeps the same height and the same horizontal distance from you, but moves away.

Picture the same thing on a two-dimensional plane and you will notice that:

  • the point shrinks, if you gave it a size;
  • it seems to move towards the centre, both vertically and horizontally. In three dimensions that is only an optical illusion, but in two dimensions it is true.

If you are not convinced yet, try an experiment. Put two bottles on a table, one behind the other. From the front, the second is hidden by the first. As soon as you step to the right, say, the back bottle appears further to the right than the front one.

And indeed, with both bottles at x = -100 (to the left, hence negative), the first at z = 10 and the second at z = 12.5, their x' values are:

x' (first bottle)  = -100 / 10   = -10
x' (second bottle) = -100 / 12.5 = -8

So on the two-dimensional plane the second bottle sits further right, because -8 > -10.

Bottles have a size and are not just points, so by the same principle the second one also looks a little smaller. This will make more sense shortly.

One important detail

On screen, the origin is the top left corner. x grows to the right and y grows downwards: that is the convention for windows and for the browser's canvas. So the values have to be mapped to the screen size, and the vertical axis flipped.

What is the intuition?

It feels right that things further from the observer drift towards the centre (think of a huge mountain range that seems to fit in the middle of your view, however many kilometres it spans) and that how much they drift depends on distance.

It also means distant things seem to move more slowly, because any movement is shrunk by the division by distance, the / z in the formula.

Why does the formula work?

The maths behind it is simple and beautiful. It only uses the fact that triangles with the same angles always keep their sides in the same proportions.

Handwritten proof with similar triangles: the eye at the origin, point P at distance z and its projection P' on the screen at distance 1, giving y' = y/z. Labels are in Portuguese.
Proof with similar triangles

Demonstration

Applying the formula in a 2D context is enough to get a sense of depth. Below, the eight corners of a cube, from (-1, -1, -1) to (1, 1, 1), are rotated around the vertical axis, pushed away from the observer (adding 4 to z) and projected with x / z and y / z. Nothing else. Each panel is the same cube at a different angle:

0°20°40°60°
The same cube, projected with nothing but x / z and y / z

With the point (1, 1) moving back from z = 1 to z = 5, its projection falls towards the origin along a straight line, exactly like the point you imagined at the window:

0x'y'z = 1z = 2z = 3z = 4z = 5
The point (1, 1) moving back: x' = 1 / z, y' = 1 / z

The code for the animated version, plain JavaScript drawing on a <canvas> element, is on GitHub: github.com/dlgiovani/simple-3D.

Green wireframe cube on a black background, drawn by the animated version of the program.
A still from the animated version

Further reading

There is more on this in the Tsoding video.

Outside the Journal, my work is integration and automation between CRM, ERP and management platforms, for companies in Portugal and across the EU. See my previous work or get in touch.