9.2 - Orthographic Projections

../_images/ortho_diagram.png

Orthographic projections are used in the engineering fields to create accurate renderings of models. They maintain parallel lines but provide no sense of depth. All vertices are projected straight onto a viewing window. The distance from the virtual camera to an object has no affect on the size of the rendered object. (In real life objects that are further from the camera appear smaller.)

This lesson describes how to create an orthographic projection and the mathematics behind its 4-by-4 transformation matrix.

The createOrthographic() function

The function createOrthographic() in the GlMatrix4x4.js file creates an orthographic projection transformation matrix. The function requires 6 parameters as shown in its function prototype below.

/** -----------------------------------------------------------------
 * Create an orthographic projection matrix.
 * @param left   {Number} Farthest left on the x-axis
 * @param right  {Number} Farthest right on the x-axis
 * @param bottom {Number} Farthest down on the y-axis
 * @param top    {Number} Farthest up on the y-axis
 * @param near   {Number} Distance to the near clipping plane along the -Z axis
 * @param far    {Number} Distance to the far clipping plane along the -Z axis
 * @return {Float32Array} The orthographic transformation matrix
 */
self.createOrthographic = function (left, right, bottom, top, near, far)

The six parameters form a rectangular cuboid that defines the visible area of a rendering. Experiment with the example below which allows you to change the parameters to a createOrthographic function call and see the resulting rendering in the second canvas window to the right. You can click and drag in the left canvas to modify your view of the virtual world.

Remember that the camera transform has already moved the world in front of a stationary camera which is at the origin looking down the -Z axis, as shown in the WebGL program below.

Experiment with an Orthographic Projection

Please use a browser that supports "canvas" Please use a browser that supports "canvas"
Manipulate parameters of createOrthographic(left,right,bottom,top,near,far):

left : -5.0 -5.0 5.0 right : 5.0 -5.0 5.0
bottom : -5.0 -5.0 5.0 top : 5.0 -5.0 5.0
near : 0.0 -5.0 15.0 far : 10.0 -5.0 15.0
Change canvas size to match aspect ratio.

Open this webgl demo program in a new tab or window

As you experiment with the orthographic parameters, please verify that you understand the following ideas:

  • Geometric primitives (points, lines, or triangles) outside the viewing volume are clipped from view. (Geometric primitives can be partially visible if they intersect one of the viewing volume boundaries.)
  • There are three renderings of the same model but each is located a different distance from the camera. Notice that all of the models are rendered the same size.
  • Notice that parallel lines in the models are parallel in the rendering.
  • If the aspect ratio of the projection’s width and height is different than the aspect ratio of the canvas’ width and height, the rendering is distorted. It is the programmer’s job to make sure the aspect ratios are consistent.
  • Values for left and right are positions along the x-axis.
  • Values for bottom and top are positions along the y-axis.
  • Values for near and far are distances from the origin along the -Z axis.
  • If near is negative, models behind the camera are rendered! (Strange but true!)
  • If the value of left is greater than the value of right, the world is mirrored about the Y-Z plane. If the value of bottom is greater than the value of top, the world is mirror about the X-Z plane. If the value of near is greater than the value of far, the world is mirror about the X-Y plane.
  • The viewing window is the front side of the viewing volume. It is defined in the lower-left corner by the point (left, bottom, near) and in the upper-right corner by the point (right, top, near).

The Orthographic Projection Matrix

Clipping Volume

As we discussed in the previous lesson, a projection matrix must transform the vertices in a scene into the clipping volume, which is a 2 unit wide cube as shown in the image to the right. This is easily done with three transformations:

  1. Translate the volume defined by the createOrthographic parameters so that it is centered at the origin, then
  2. Scale the volume to be a 2 unit wide cube using an appropriate scale factor for each axis, and then
  3. Flip the z axis to match the clipping space’s coordinate system.

Let’s discuss the details of each step.

Center the Viewing Volume at the Origin

Let’s use a parametric equation to calculate the mid-point between two values. The mid-point is calculated when t is equal to 0.5. Therefore, the mid-point between left and :code`right` can be calculated like this:

mid_x = (1-0.5)*left + (0.5)*right;  // t = 0.5

This reduces to the simple addition of left and right divided by 2.

mid_x = (left + right) / 2;  // t = 0.5

The center of the viewing volume can be calculated using three such equations. The values of near and far are distances along the -Z axis. Negating them converts them into Z-axis locations.

mid_x = (left + right) / 2;
mid_y = (bottom + up) / 2;
mid_z = (-near + -far) / 2;

Therefore, we can translate the viewing volume to make it centered about the global origin using this transformation matrix:

centerAboutOrigin
=1
0
0
0
0
1
0
0
0
0
1
0
-mid_x
-mid_y
-mid_z
1
Eq1

Scale the Viewing Volume

Scaling requires a simple ratio. If the current width of the viewing volume is 10 units wide, scaling the values to 2 units wide requires a scale factor of 2/10, or 1/5. Our scale factors must be:

scale_x = 2.0 / (right - left);
scale_y = 2.0 / (up - bottom);
scale_z = 2.0 / (far - near);

Our scaling transform looks like this:

scaleViewingVolume
=scale_x
0
0
0
0
scale_y
0
0
0
0
scale_z
0
0
0
0
1
Eq2

Switch Coordinate Systems

The only difference between a right-handed and left-handed coordinate system is the direction of the z-axis. Vertices can be switched between the two systems by multiplication of the z component by -1. Therefore, this transformation inverts the the coordinate system:

convertToLeftHanded
=1
0
0
0
0
1
0
0
0
0
-1
0
0
0
0
1
Eq3

The Orthographic Projection Transform

Conceptually an orthographic transformation is composed of these three sequential transformations applied from right to left:

1
0
0
0
0
1
0
0
0
0
-1
0
0
0
0
1
*scale_x
0
0
0
0
scale_y
0
0
0
0
scale_z
0
0
0
0
1
*1
0
0
0
0
1
0
0
0
0
1
0
-mid_x
-mid_y
-mid_z
1
*x
y
z
1
=x'
y'
z'
w'
Eq4

Click on the multiplication sign in the above equation to see the results. If you simplify the terms, you get this transformation:

2/(right-left)
0
0
0
0
2/(top-bottom)
0
0
0
0
-2/(far-near)
0
-(right+left)/(right-left)
-(top+bottom)/(top-bottom)
-(far+near)/(far-near)
1
Eq5

Summary

If you want to understand complex transformations, break them down into their elementary steps.

An orthographic projection does not modify the relative relationships between vertices and therefore an object’s size does not change as it moves closer to (or farther away from) the camera.

An orthographic projection prepares vertices for clipping, which is the next stage of the graphics pipeline.

Glossary

orthographic projection
Transform the vertices of a 3D model into normalized device coordinates in preparation for clipping. A rendering maintains parallel lines and all models retain their size.

Side Note: Transformation derivations are typically not unique.

The above derivation of an orthographic transformation is not unique. For example, here is another way to think about getting the orthographic viewing volume into the clipping volume. Remember that near and far are distances and their values must be negated to convert them to positions along the -Z axis.

  1. Translate the (bottom,left,-far) corner to the origin.
  2. Scale the viewing volume to a 2x2x2 cube.
  3. Translate the result by (-1,-1,-1).
  4. Flip the z axis to match the clipping space’s coordinate system.

A series of transforms to perform these operations is:

1
0
0
0
0
1
0
0
0
0
-1
0
0
0
0
1
*1
0
0
0
0
1
0
0
0
0
1
0
-1
-1
-1
1
*2/(right-left)
0
0
0
0
2/(top-bottom)
0
0
0
0
2/(-far-(-near))
0
0
0
0
1
*1
0
0
0
0
1
0
0
0
0
1
0
-left
-bottom
-(-far)
1
*x
y
z
1
=x'
y'
z'
w'
Eq6

If you simplify the terms in the result and compare each term to our previous results you will verify that we get the same answer. This is a good example of the fact that there is often multiple ways to accomplish a desired result.

Next Section - 9.3 - Perspective Projections