The Projection Transform looks like this:
Let \pvcs = (x, y, z, 1) and let \pccs = (x', y', z', w'). Then
From the transformation matrix above, y' = F y + B z. Consider a 2D slice at x = 0 through the view volume (shown on the left below) and the corresponding 2D slice at {x' \over w'} = 0 through the canonical view volume (shown on the right below):
Points on the top line of the view volume satisfy {y \over -z} = {t \over n}. That is, there points are of the form ({-tz \over n} , z). These points correspond to points on the top line of the canonical view volume that satisfy {y' \over w'} = 1.
Substitute a point ({-tz \over n} , z) into the y' and w' lines of the transformation matrix:
As stated above, the VCS point ({-tz \over n} , z) is transformed to a CCS point for which {y' \over w'} = 1. So
So we know that
By a similar argument (using VCS points ( {-b z \over n}, z ) on the bottom line which map to CCS points for which {y' \over w'} = -1) we can show that
We can then solve the two equations in F and B to get:
This is done analagously to y'.
Given \ell and r which are the left and right limits in the x direction of the view volume, we apply the same method as for y' and get
VCS points on the near plane ( z = -n ) map to CCS points on the line {z' \over w'} = -1, and VCS points on the far plane ( z = -f ) map to CCS points on the line {z' \over w'} = +1.
From the transformation matrix:
Substitute z = -n to get one equation. Substitute z = -f to get another equations. The unknowns are C and D:
Solving the equations yields:
Bringing everything together:
Other VCS-to-CCS transformation matrices exist. In particular, orthographic projection is sometimes used.
See functions frustum(), perspective(), and ortho() in 00-intro/src/linalg.cpp in openGL.zip.