8.1 - Introduction to Projections¶
When you render a 3-dimensional computer graphics scene, you create a 2-dimensional picture of the 3D scene. The picture is a projection of the models in the scene onto a 2-dimensional “screen”. Therefore it is logical to call this operation in the graphics pipeline a projection.
There are two standard projections used in computer graphics. An orthographic projection maintains parallel lines but provides no sense of depth. A perspective projection provides for a sense of depth, but parallel lines are skewed toward vanishing points. Orthographic projections are used in the engineering fields when an accurate representation of a model is desired. Perspective projections are used when a “real life” view of a scene is desired. Perspective projections simulate how the human eye sees the real world. Please study the following two examples and compare their outputs. You can rotate the view in both windows with a mouse click and drag.
An example of an orthographic projection. Notice that:
- Parallel lines stay parallel.
- There is no perception of depth. (The duplicated object in the background looks as big as the center object.)
An example of a perspective projection. Notice that:
- Parallel lines of the model are not parallel in the rendering.
- You can perceive depth. (The off-center object changes size as its distance from the camera changes.)
Each step in the graphics pipeline is performing a specific task but also preparing data for follow-on steps. This is especially true for the projection transform.
- The major task of a projection transformation is to project a 3D scene onto a 2D screen.
- A projection transformation also prepares for these follow-on tasks:
- Clipping - the removal of elements that are not in the camera’s line of sight.
- Viewport mapping - convert a camera’s viewing window into the pixels of an image.
- Hidden surface removal - determining which objects are in front of other objects.
Before a projection operation a (x,y,z) vertex represents a location in 3-dimensional space. After a projection the meaning of the values have changed:
- The (x,y) values of a vertex represent its location on a 2-dimensional screen.
- The z value represents the distance of the vertex from the virtual camera and is used for hidden surface removal.
- All 3 values, x, y, and z, are used for clipping, which removes points, lines, or triangles that are not visible to the scene’s virtual camera.
Before we jump into the details of projections, we need to discuss the standard clipping volume that all scenes are mapped into before they are rendered.
The Clipping Volume¶
When you point a real camera at something to take a picture, only a part of the real-world is visible in the camera’s field-of-view. The same is true of the human eye; you only see what is in front of you. We want the same behavior for our virtual scenes. The process of determining what is visible and what is not visible is called clipping. Clipping is done automatically by WegGL. To make clipping as efficient as possible, clipping is done using a cube centered at the origin.
The clipping volume is defined in Normalized Device Coordinates (NDC) which is a 2 unit wide cube, with the X axis going from -1 to +1, the Y axis going from -1 to +1, and the Z axis going from -1 to +1, as shown in the image to the right.
Did you notice that the clipping volume is defined in a left-handed coordinate system? The Z-axis is pointing into the page. Wow! Previous lessons have stated that WebGL always uses a right-handed coordinate system and now it doesn’t. What is going on?
The short story is this: the hardware GPU that produces the graphics is designed for speed and efficiency, while the WebGL API is designed for programmers. Most people are right handed, so for most people the right-hand rule feels natural and comfortable, while the internal workings of the graphics hardware can typically be ignored. The projection matrix is the last operation under programmer control that manipulates the geometric data of a scene. So the projection transformation can convert to a left-handed coordinate system and not affect anything the programmer has done with the geometric data in a right-handed coordinate system.
You can visually see the left-handed coordinate system of the GPU in the following demo program. Observe what happens when you include an projection matrix and when you don’t.
Render 3 triangles with or without a projection matrix.
- The red triangle is at z = -0.25
- The green triangle is at z = 0.0
- The blue triangle is at z = +0.25
Use a projection matrix for rendering
Open this webgl program in a new tab or window
Given that the clipping volume uses a left-handed coordinate system, there are two very important implications to the graphics programmer:
- You must always include a projection matrix in your vertex transform, even if you don’t think you need one. All of the transformations we have defined previously assumed a right-handed coordinate system. If you don’t include a projection matrix, all of the other transformation matrices will not work correctly.
- If you create your own projection matrix, it should negate the z values of all vertices.
Clipping¶
Consider how clipping points might be done using programming logic. To determine if a point defined as (x,y,z) is inside the clipping volume, you could write code like this:
if (x >= -1 and x <= 1 and
y >= -1 and y <= 1 and
z >= -1 and z <= 1)
point_is_visible = true;
else
point_is_visible = false;
However, since the clipping volume is uniform and symmetrical about the origin, we can simplify this code using an absolute value function:
if (abs(x) <= 1 and abs(y) <= 1 and abs(z) <= 1)
point_is_visible = true;
else
point_is_visible = false;
Furthermore, you could set the boolean value with just a simple assignment like this:
point_is_visible = (abs(x) <= 1 and abs(y) <= 1 and abs(z) <= 1)
Actually clipping is done in homogeneous coordinates (which you will learn more about in a couple of lessons). For a (x,y,z,w) vertex, the clipping test would be
point_is_visible = (abs(x) <= w and abs(y) <= w and abs(z) <= w)
But the details don’t matter to most programmers. What does matter is that the symmetrical design of the clipping volume facilitates fast clipping. It is helpful to remember that WebGL is really a hardware specification with a software API (application programmer interface). WebGL’s design is optimized for hardware implementation.
When Does a Projection Need To Happen?¶
A projection transformation must happen after a scene has been moved in front of a virtual camera, but before clipping occurs. A projection operation can be performed using a 4-by-4 matrix multiplication, so it is typically combined with the model transform and the camera (or view) transform that have been conceptually performed in previous stages of the pipeline. In reality, the model, view, and projection transformations are typically performed with a single matrix multiplication. In your JavaScript code you will typically create a single transformation matrix and pass it to your vertex shader.
*ViewMatrix
*ModelMatrix
Eq1
The following lessons describe how to build a 4-by-4 projection matrix.
Glossary¶
- projection
- Transform the vertices of a 3D model into 2D points on a 2D viewing window.
- viewing window
- A rectangular 2D region on which a 3D world is projected.
- orthogonal projection
- Project all vertices of a 3D model along straight lines parallel to the Z axis.
- perspective projection
- Project all vertices of a 3D model along vectors to the camera’s location. Where the vector hits the 2D viewing window becomes it’s rendered location.
- clipping
- The process of determining what is visible and not visible in a virtual camera’s field of view.
- Normalized Device Coordinates (NDC)
- The 3D coordinate system that all scenes are converted into before clipping is performed.