Perspective Projections
Perspective projections are more commonly used
and require some additional effort to derive.
The first step is choosing the form of the matrix. A simple version which
projects onto the plane given by z=-d was given earlier by
The more complex transformation we wish to perform will in addition need the ability
to scale and translate each of x, y, and z. The following matrix has all
the correct elements in place.
The choice of the coefficient of -1, which makes h' = -z, is arbitrary.
Scaling this number can be matched by scaling each of the other parameters.
Let's first look at how y gets mapped to y'.
For y = -z*top/near, we would like y'/h' = 1.
Thus,
(-F*z*top/near + B*z)/(-z) = 1
Similarly, for y = -z*bottom/near, we would like y'/h' = -1.
Thus,
(-F*z*bottom/near + B*z)/(-z) = -1
Solving these two equations for F and B gives
F = 2 near/(top-bottom)
B = (top+bottom)/(top-bottom)
The mapping for x is determined in an analogous way, giving
E = 2 near/(right-left)
A = (right+left)/(right-left)
Lastly, let's look at the mapping for z.
For z=-near, we would like z'/h' = -1. Thus
C(-near)/near + D/near = -1 .
For z=-far, we would like z'/h' = 1. Thus
C(-far)/far + D/far = 1
Solving these equations for C and D gives:
C = -(far+near)/(far-near)
D = -2*far*near/(far-near)
OpenGL calls for Perspective Projections
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
followed by one of:
glFrustum(left, right, bottom, top, near, far)
gluPerspective(fovy, aspect, near, far)
The glFrustum() call uses the parameters as
described above.
An alternative specification is to use field-of-view and
an aspect ratio to specify the image plane parameters.
In gluPerspective(), fovy gives the field-of-view
in the y-direction, measured in degrees and centred about y=0. The
aspect ratio gives the relative horizontal size of the image, centred
about x=0.
Non-linearity in Perspective Transformations
The perspective transformations produce a z-coordinate for
use in visibility calculations. It is, however, a non-linear function
of the original z coordinate. To illustrate this, consider
a railroad viewed in perspective as follows.
tracks
left: x= -1, y= -1
right: x= 1, y= -1
view volume
left = -1, right = 1
bot = -1, top = 1
near = 1, far = 4
In this scene, what happens to z in VCS and NDCS
as we move along the track?
The following expressions tell us what we wish to know.
It can be directly seen that z_NDCS is a non-linear function
of z_VCS.
What does this look like in the image plane?
Let's determine z_VCS as a function of x_NDCS.
With this we can point at the image and ask
What is the real distance of this point?
Lastly, what does the train track look like in NDCS?
Straight lines in VCS correspond to straight lines
in NDCS, although the 'speed' at which one moves along
them is not the same in the two coordinate systems.