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.. – Jaroslav Jerryno Novotny Mar 31 '15 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. – Mutant Bob Mar 31 '15 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 ! – Chebhou Apr 1 '15 at 19:44