# What are the formulas to define the camera's view cone?

What are the formulas to calculate the 4 half-planes that define the camera's view volume?

The inputs should be the camera's world matrix, focal length (and maybe sensor size?) and anything else I overlooked. I am not interested in the clipping start/end, but extra credit if you include them.

I plan to use this to calculate if an object would be visible to the camera, (which is slightly harder since the origin could be off-camera, but polygons could still be on-camera, but I can fudge that).

• You should cull the objects with bounding-spheres to avoid the origin problem, its fast. Search for frustum culling, this question is more for Game development stack exchange than blender.. Commented Mar 31, 2015 at 17:04
• It is not for game. I want to add more objects (part of a lattice) to the scene, but not in places where they will never be rendered. I could easily add 100,000 objects and only have 10,000 actually show up on camera, so I'd rather just add only the ones that will appear on camera. Commented Mar 31, 2015 at 20:46

After a couple of quick experiments I determined that for a square camera the following coordinates (expressed in the camera's local coordinate system) would appear in the corners of the image:

x = y = sensor_width/lens /2
[±x, ±y, -1]


For a rectangular image, whichever dimension is larger becomes sensor_width/lens/2, and the smaller dimension is proportionally adjusted.

To define the half-planes in the camera's coordinate system, it's enough to calculate the cross products of the vectors pointing at the vertices of each edge, so

lr = [ x,-y,-1]
ur = [ x, y,-1]
ll = [-x,-y,-1]
ul = [-x, y,-1]
n1 = | lr × ll |
n2 = | ll × ul |
n3 = | ul × ur |
n4 = | ur × lr |


We normalize the vectors to length 1 so that we can use them in distance calculations later on.

When you want to determine if a particular coordinate c is in the camera's view cone convert it to camera local coordinates using

M = cam.matrix_world.inverted()
c2 = M c


Now that we have c2 (in the camera's coordinate system) we can compute the dot product between it and the various half-plane normals.

zi = ni ∙ c2


If all those zis are >=0 then the point is in the camera's view cone. If the original coordinate is for an object, it's useful to incorporate a fudge factor like the radius of the object's bounding sphere (centered on the coordinate) and make sure that zi >= -fudge .

And this is the python class based on all that math:

class CameraCone:

def __init__(self, matrix, sensor_width, lens, resolution_x, resolution_y):
self.matrix = matrix.inverted()
self.sensor_width = sensor_width
self.lens = lens

w = 0.5* sensor_width / lens
if resolution_x> resolution_y:
x = w
y = w*resolution_y/resolution_x
else:
x = w*resolution_x/resolution_y
y = w

lr = Vector([x,-y,-1])
ur = Vector([x,y,-1])
ll = Vector([-x,-y,-1])
ul = Vector([-x,y,-1])
self.half_plane_normals = [
lr.cross(ll).normalized(),
ll.cross(ul).normalized(),
ul.cross(ur).normalized(),
ur.cross(lr).normalized()
]

def from_camera(cam, scn):
return CameraCone(cam.matrix_world, cam.data.sensor_width, cam.data.lens, scn.render.resolution_x, scn.render.resolution_y)

def isVisible(self, loc, fudge=0):

loc2 = self.matrix * loc

for norm in self.half_plane_normals:
z2 = loc2.dot(norm)
if z2 < -fudge:
return False

return True

• this is great ! Commented Apr 1, 2015 at 19:44

Small correction for the previous answer:

line "loc2 = self.matrix * loc" should be "loc2 = self.matrix @ loc" for the newer versions of Blender