I am working on a renderer of sorts and I have some fundamental questions. Let's say I have a vector in a 3D virtual world space which is unitless, and I want to project it onto a 2D screen, so I need its pixel position.

My background is in computer vision, so this is how I would model the problem.

p = K * [R | t] * v

where v is my 3D vector in homogenous coordinates. R is a 3x3 rotation matrix, t is a 3x1 translation vector, and K is a 3x3 "camera matrix". The camera matrix takes the following form

f 0 cx
0 f cy
0 0 1

f is the "focal length" of the virtual camera and cx, cy is the "principal point" in pixels (usually the center of the screen).

So, assuming my camera is at the origin (and static), [R | t] moves the 3D vector v somewhere in front of the camera and I get some v'. Now, I want to project 3D vector v' onto the screen.

v' = [x' y' z']^T

Kv' = [fx*x'+cx fy*y'+cy z']^T

Now, dividing by the perspective z' I get p.

p = [(fx*x'+cx)/z' (fy*y'+cy)/z' 1]^T

This certainly works in code and I'm getting favorable results in my renders.

But I fundamentally don't understand what it means to express focal length in terms of pixels. In a real camera it's the physical distance between the imaging plane and the focal point of the lens, but there's no such analog in 3D graphics.

Furthermore, I don't really see why the dimensional analysis works out, and why p is indeed in units of pixels.

Thanks for reading!

  • \$\begingroup\$ Hint: your monitor has both a pixel resolution and a width in real 3D space, and it forms an image plane that's positioned on one side of a lens (the one in your eye). ;) \$\endgroup\$ – DMGregory Jan 11 at 4:54
  • \$\begingroup\$ Hm I don't quite understand what you mean by that. I agree that the monitor has a pixel resolution and a width in real 3D space. But isn't the "image plane" of the virtual camera the monitor itself ? Where does the focal length come in? \$\endgroup\$ – Carpetfizz Jan 11 at 5:02
  • 1
    \$\begingroup\$ One minor note: "Let's say I have a vector in a 3D virtual world space which is unitless" Just because you haven't named your unit or associated it with a real-world measure doesn't make it unitless, the way that, say, an aspect ratio is unitless. For the purposes of dimensional analysis it still has a unit of "one game world-space unit" whatever you choose that to be. This is important when we're looking at areas or volumes or speeds or accelerations of objects in the game world - that game unit behaves just like a real-world spatial unit like metres in these equations. \$\endgroup\$ – DMGregory Jan 11 at 13:07

In a real camera it's the physical distance between the imaging plane and the focal point of the lens

Well, where's our image plane? The monitor's surface.

Where's the focal point, the place where the rays connected our image plane converge/cross over at a point? The player's eye.

So the distance here relates to the distance of the (idealized) viewer's face from the monitor.

Diagram comparing the focal length of a lens projecting onto a film/sensor, versus the analogous geometry of an eye in front of a monitor

Here the direction of those rays is reversed - instead of light flowing from the focal point onto the image plane where it hits a sensor/film to be detected & recorded in an image, instead light shines from the image plane on the monitor into the focal point of the viewer's eye. But the trigonometry works out similarly in each case.

Why is it measured in pixels? Because that's the dimension you've chosen to measure your image plane. A monitor with square pixels of a particular resolution also has a particular dimension in real-world space, giving us an exchange rate between image units like pixels and real-world spatial units like cm. So you can think of the distance between the viewer & monitor being measured in cm and converted to pixels using assumptions about a typical monitor.


Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.