The purpose of this blog post is to jot down a few handy tips and tricks worth remembering working with view frustums, ranging from the blatantly obvious to the more obscure. I don’t spend as much time reviewing these posts as I would like, so as ever, please feel free to comment with any corrections or related tips.
Inverse View Matrix
A cameras view matrix is most often represented as a homogeneous 4×4 matrix used to shift bases, transforming points from world space, to the camera’s own three-dimensional co-ordinate system (‘camera space’ or ‘view space’). However a cameras inverse view matrix can also have it’s uses. A camera’s inverse matrix represents the position and orientation of the camera it’s self within the world and can therefore prove useful in the following scenarios:
- When rendering game cameras within the world, perhaps useful when debugging or writing tools which deal with the positioning/manipulation of multiple cameras
- Extracting the camera’s translation and orientation when these values are not immediately available/accessible
Finding View Frustum Vertices
Sometimes it can be useful to find the world space vertices which define the corners of the view frustum, perhaps to render the frustum, or to find the distance to a particular point or edge. Given the position, orientation, aspect ratio and FOV of a camera it is possible to manually calculate the frustums corners, however a much more elegant approach is at hand.
Start by setting up the vertices of a cube with it’s local extents representing the clip-space of your graphics pipeline (OpenGL uses [-1,-1,-1]→[1,1,1] for clip-space whereas DirectX uses [-1,-1,0]→[1,1,1]). Next, transform this ‘clip space cube’ by the camera’s inverse projection matrix. This will reveal the corners of the view frustum in view space. Further transforming these points by the camera’s inverse view matrix will yield the world-space vertices representing the corners of the view frustum.
Caching View Frustum Data
This one may seem pretty obvious, but calculating data such as frustum planes, corners and angles can be computationally expensive and need only be carried out whenever the camera is moved or re-oriented. If your camera class has Set methods for properties such as position, lookat, FOV etc, it may be wise to check that the new value is unique before setting, re-calculating or storing any new data.
Storing View Frustum Planes / Normals
As planes can be represented using a pair of vectors (position and a unit normal) or better still in a single vector (ax + by + cz + d = 0), it might seem sensible to store a vector or vector pair per frustum plane. It is worth considering however that view frustums are almost always symmetrical and therefore calculating and storing only the left/top plane may be beneficial in some cases. When the right/bottom planes are required they can be generated on the fly by reflecting the left/top planes about the cameras local axis. If the view frustum is always parallel to a world axis this fact can be exploited by storing only the left/top frustum planes and simply inverting the appropriate component of the point/normal vectors to perform the reflection. Frustum planes can also be extracted directly from the camera’s view/projection matrix on the fly, see Fabian “ryg” Giesen’s excellent blog post for more information.