10
votes

I am confused about perspective projection.

Here is the scenario that is confusing me. My frustrum's front plane is basically positioned at at positive z-axis and the back plane at a negative axis and rotated about some deg along the posive z-axis.

Now, whenever I go through examples I see that the near and the far plane are all present in the negative z axis.

My approach in this case was basically something like:

glMatrixMode(GL_PROJECTION);    
glLoadIdentity();
glFrustrum(-xval,+xval,-yval,+yval,-10,+10);
gluLookAt(); // some point lying on this axis of symmetry about the point
glMatrixMode(GL_MODELVIEW);

So, in the above case what is the behavior that I should expect for the glFrustum with a negative as well as positive value for z. i.e. in this case -10 to +10.

3
"the back plane at a -ive axis " I've never heard of the "ive" axis. Can you elaborate on that, or is it just a typo? Also, never put the "lookat" matrix in the GL_PROJECTION matrix. It goes in GL_MODELVIEW.Nicol Bolas
i mean that the front plane is present along the +ive z a-xis and the back plane present at -ive z axis. Something like glFrustrum(-xval,+xval,-yval,+yval,-10,+10); where the near plane becomes +10 along z axis and far plane becomes -10 along z-axisJohn Cassidy
'+ive' as in 'positive' then and '-ive' as in 'negative'?Bart
I've being doing graphics off and on for over a decade. I aced two semesters of graphics in college. And I've never heard of the "+ive z axis" or the "-ive z axis". There is simply the Z axis, which goes in the positive and negative directions.Nicol Bolas
yes exactly sorry for the weird language. Positive z axis and the negative z axisJohn Cassidy

3 Answers

7
votes

The view volume defines how much of the world you actually see, every object outside the view volume is not visible, and everything inside is potentially visible(if not obscured by an object in front of it).

The shape of the view volume is determined by the type of projection you use.

There are 2 types of projections ortographic and perspective projections.

Ortographic don't take distance from viewer into account (not natural but useful for CAD software etc.) and perspective projections which take the distance from the viewer into account and therefore objects that are further away appear smaller.

In an ortographic projection the view volume is a cube and in a perspective projection the view volume has the shape of a frustum (near clipping plane is smaller than the far clipping plane).

In either case the contents of the view volume are "projected" onto the near clipping plane.

Of course, the process is a little bit more involved than simple projection_matrix multiplication with every vertex in the view volume; but it's basically explained in almost every OpenGL related book.

The view volume shape models camera properties to some extent...how wide you see, how far you see etc.

The red book explains this well in the dedicated viewing chapter.

When talking about a frustum you imply you are using a perspective projection.

To construct an frustum you need 8 points and you'll generally want to construct a symmetrical frustum which simplifies the projection matrix.

Instead of specifying the 8 points directly by hand you'll use helper methods like gluPerspective(fovy,aspect_ratio,near,far) which uses "more intuitive" parameters for frustum construction; it's is basically a wrapper around glFrustum which calculates the 8 points for you and then calls glFrustum instead of you.

For OpenGL 3.0 and higher you'll provide your own implementation of gluPerspective, you can simply google the code.

Just remember projection makes 3D become 2D.

Regarding viewing, OpenGL uses a right-handed coordinate system (x axis points left, y axis point up and z axis point outward the screen.); DirectX uses a left-handed coordinate system.

Remember, in 3D space you only have 2 coordinate system orientations(left and right handed).

What makes the difference is the orientation of the z axis; if you make z axis point inwards it's a left-handed system or if you make z point outward it's a right-handed system.

Any other direction for the z axis wouldn't make the z axis perpendicular to the x and y axes and therefore you wouldn't have a coordinate system.

The handedness determines stuff like in which direction the positive rotation occurs and so on.

Your camera is located at the origin (0,0,0) and is facing down the -z axis by default; and it will be like that until you don't apply some kind of transformation.

Your view frustum is constructed around the viewing direction and the near clipping plane is located at z = -near from the camera which is located at the origin initially.

When you specify near and far as positive values to glFrustum you haven't specified their z location it just so happens that near clipping plane is located at z=-near because of the default orientation of the camera along the negative z axis and because the camera is at the origin (0,0,0)initially and your near clipping plane is always near away from the viewers eye position a.k.a camera position.

And whenever you change your view (change camera position or change camera orientation or both) your frustum will still be "wrapped around the new view direction" and the near clipping plane will still be "near" away from the new camera position.

Hopefully, you get the concept.

Frustum defines how much.

No matter where the camera stands and point to.

4
votes

So, in the above case what is the behavior that I should expect for the glFrustum with a negative as well as positive value for z. i.e. in this case -10 to +10.

Broken. You should expect the behavior to be broken.

The documentation is quite clear on this:

nearVal, farVal: Specify the distances to the near and far depth clipping planes. Both distances must be positive.

(emphasis added)

Passing a negative number (or zero) for these values will produce badness.

2
votes

Now, whenever I go through examples I see that the near and the far plane are all present in the -ive z axis.

Of course. Otherwise you would get something like this

:enter image description here

All projection happens relative to the origin 0. near and far determine the distance of the clipping planes from the origin. left and right define the opening angle of the frustum together with the near plane. If you place a "near" and far plane in opposite directions of the origin, your projection space becomes shaped like an hourglass.

glMatrixMode(GL_PROJECTION);    
glLoadIdentity();
glFrustrum(-xval,+xval,-yval,+yval,-10,+10);
gluLookAt(); // some point lying on this axis of symmetry about the point
glMatrixMode(GL_MODELVIEW);

The projection is not meant to place the view. The projection is sort of the "lens" of your virtual camera. You can use it to tilt and shift your lens and set the "focal length". But it's not meant to "place your camera". This should happen through the modelview matrix.

So, in the above case what is the behavior that I should expect for the glFrustum with a negative as well as positive value for z. i.e. in this case -10 to +10.

From the far to the "near" plane, objects will become larger as they approach 0, for Z=0 they're in a singularity and blow up infinitely, and then getting closer to near they will become smaller but will be inverted, i.e. rotated by 180° around the Z axis, and depth values being turned around, i.e. depth sorting by depth testing will reject fragments closer to near than to 0.