Camera Basis Vectors and Perspective Projection Matrix

To define a perspective camera for CG related tasks, we need some basic information such as camera position (camPos), look at position (lookAt), field of view (fov), distance to near (dNear) and far (dFar) clipping planes, and finally ratio.

Camera position and lookAt are needed to define camera basis vectors, which are used to define camera matrix (C). We transform objects from world to camera space using inverse of camera matrix (invC) or from camera space to world space (using camera matrix). Objects (meshes) should be in camera space for the tasks such as backface culling, clipping and projection.

fov,  distance to near (dNear) and far (dFar) clipping planes, and ratio are used for perspective projection and frustum culling.

I used right-handed coordinate system for Enginator5000. So, I will explain everything in right-handed coordinate system.

Generate Camera Basis Vectors

Remember, in right handed coordinate system, if your origin is screen of the computer, +z is towards you, +y is towards ceiling, and +x is towards your right. To define camera basis vectors, we need to find three basis vectors. After we find these vectors, we will put them into a 4×4 matrix, and get camera matrix C.

Generally, people name camera basis vectors as u, v, w. I prefer to name them as camX, camY, and camZ. You can use whatever you want. Basis vectors are located in the C matrix as below:

And you can calculate these vectors as below (C++ and GLM):

Defining Perspective Projection Matrix

Perspective projection gives us realistic rendering results; however, it is not the only kinds of projections used in CG and video games. You can check this website to get an idea.

We define perspective projection matrix as below:

Where, n is distance to near plane (dNear), f is distance to far plane (dFar), r is right point on the near plane, l is left point on the near plane, t is top point on the near plane, and b is bottom on the near plane.

For more details, and derivation, you can check Sogho.ca, ScratchaPixel, OGLdev or Schabby’s blog.

We calculate the values (r, l, t, b) as below (C++):