Processing math: 0%
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