3
votes

I was wondering how I might adjust a perspective projection to make it look like it was orthographic. For example, say I had a 10x10 grid of points, each with different z values, which under an orthographic projection all lines up nicely. Under a perspective projection it will of course adjust the positions relative to the camera and the z depth. What adjustments do I need to make to each point appear as though it is still lined up and in an orthographic projection? (Until the camera moves of course).

I'm thinking along the lines of calculating a ray from the eye position through the z plane (if that's what you'd call it) at the point at which I'd like it to appear and following the ray until the required depth. Although I'm not really sure how to implement this.

2

2 Answers

0
votes

The typical OpenGL projection matrix (what you get from glFrustum or gluPerspective) puts the camera point at the origin. The plane of projection is at (0, 0, -1): one unit in front of the camera.

So for a given vertex, what you need to find is the X and Y positions you would get for a projection onto the (0, 0, -1) plane. This is technically "ray tracing", but since it's an axis-aligned plane, and the camera is at the origin, it really is just simple arithmetic:

vec3 newPosition = oldPosition * (-1.0 / oldPosition.z);

Note that interpolating parameters under this perspective projection will be linear in window space, not eye/camera-space. That is, there will be no perspective correct interpolation.

Also, note that the above "simple arithemtic" does not take into account FOV. To handle that, you need to transform the X and Y of oldPosition by the upper-left part of the perspective matrix. Or just extract the 0,0 and 1,1 values from the projection matrix and multiply them with the X and Y of oldPosition. That takes care of the scaling.


One more note, since you did not state the overall goal of this.

OpenGL does not require you to render an entire scene with a single projection matrix. You can render some of a scene orthographically, while using a perspective matrix for the rest. This is often done in games, where the HUD and text elements are rendered orthographically, while the game itself is in a 3D perspective.

If this is what you're doing, all you need to do is something like the following:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(...);
glMatrixMode(GL_MODELVIEW);

//Render my perspective stuff here.

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(...);
glMatrixMode(GL_MODELVIEW);

// Render my orthographic stuff here.

You may want to turn off depth tests during the orthographic rendering, if you have ortho objects that overlap the perspective ones.

-1
votes

If you are using OpenGL you don't have to implement/calculate anything. All you will need to do is setup your camera to an orthographic projection using glOrtho and then setup your scene (your grid of 3D points).

Later when the camera moves you can catch this event and "reset" the camera to a perspective projection using glFrustum or gluPerspective. But do make sure you really want to do this - changing projections abruptly doesn't look good.

If you are looking for the mathematics of camera projections I would recommend this link.

http://www.songho.ca/opengl/gl_projectionmatrix.html