up to Schedule & Notes

The Projection Matrix

$$ \def\pocs{p_\textrm{ocs}} \def\pwcs{p_\textrm{wcs}} \def\pvcs{p_\textrm{vcs}} \def\pccs{p_\textrm{ccs}} \def\pndcs{p_\textrm{ndcs}} \def\pdcs{p_\textrm{dcs}} \def\Oocs{O_\textrm{ocs}} \def\Owcs{O_\textrm{wcs}} \def\lh{-\hspace{-0.2in}} \def\rh{\hspace{-0.2in}-} $$

The Projection Transform looks like this:

$\pccs = \begin{bmatrix} E & 0 & A & 0 \\ 0 & F & B & 0 \\ 0 & 0 & C & D \\ 0 & 0 & -1 & 0 \\ \end{bmatrix} \; \pvcs$

Let $\pvcs = (x, y, z, 1)$ and let $\pccs = (x', y', z', w')$. Then

$\begin{bmatrix} x' \\ y' \\ z' \\ w' \end{bmatrix} = \begin{bmatrix} E & 0 & A & 0 \\ 0 & F & B & 0 \\ 0 & 0 & C & D \\ 0 & 0 & -1 & 0 \\ \end{bmatrix} \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix}$

How $y'$ is Calculated

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:

$\begin{array}{rl} y' & = F y + B z \\ & = F {-tz \over n} + Bz \\ w' & = -z \end{array}$

As stated above, the VCS point $({-tz \over n} , z)$ is transformed to a CCS point for which ${y' \over w'} = 1$. So

$\begin{array}{rl} {y' \over w'} & = { {F { -tz \over n} + Bz } \over -z } & = {t \over n} F - B & = 1 \end{array}$

So we know that

${t \over n} F - B = 1$.

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

${b \over n} F - B = -1$.

We can then solve the two equations in $F$ and $B$ to get:

$\begin{array}{rl} F & = {2 n \over t-b} \\ B & = {t+b \over t-b} \end{array}$

How $x'$ is Calculated

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

$\begin{array}{rl} E & = {2 n \over r-l} \\ A & = {r+l \over r-l} \end{array}$

How $z'$ is Calculated

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:

$\begin{array}{rl} z' & = C z + D \\ w' & = -z \end{array}$

Substitute $z = -n$ to get one equation. Substitute $z = -f$ to get another equations. The unknowns are $C$ and $D$:

$\begin{array}{rl} {z' \over w'} & = {{C (-n) + D} \over n} \\ & = -C + {D \over n} \\ & = -1 \\ \\ {z' \over w'} & = {{C (-f) + D} \over f} \\ & = -C + {D \over f} \\ & = +1 \end{array}$

Solving the equations yields:

$\begin{array}{rl} C & = {f+n \over n-f} \\ D & = {2fn \over n-f} \end{array}$

The VCS-to-CCS Transformation Matrix

Bringing everything together:

$\pccs = \begin{bmatrix} {2n \over r-l} & 0 & {r+l \over r-l} & 0 \\ 0 & {2n \over t-b} & {t+b \over t-b} & 0 \\ 0 & 0 & {f+n \over n-f} & {2fn \over n-f} \\ 0 & 0 & -1 & 0 \end{bmatrix} \; \pvcs$

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.

up to Schedule & Notes