Reversing perspective foreshortening.

Hi. I have a 3D scene that I am rendering in a perspective projection. I have a camera that I use to orbit around the scene, always looking at the origin. In addition the scene itself can translate and rotate. In my scene I have 3D objects that get smaller as they get farther away from the camera as you would expect in a perspective projection. I want some 3D objects to remain the same size regardless of where they are in the scene. In a GLSL vertex shader I managed to linearize gl_Position.z and then reverse the foreshortening by doing the following…

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position.z = (gl_Position.z / 40.0) * gl_Position.w; // Linearize depth. 40 is the far plane.
gl_Position.w = 1.000;

Unfortunately now my 3D objects are in the wrong place in the scene. I suspect I may need to do something with gl_Position.x and gl_Position.y?

Any help would be appreciated.

At the top of the projection matrix I have glFrustum while at the top of the modelview matrix I have gluLookAt followed by the scene.


Then you’ll need to adjust the transformation based upon the position of the object as a whole. You can’t do it for individual vertices without considering the object to which they belong.

One option is to scale the vertices relative to the object’s origin in proportion to the eye-space Z coordinate of the object’s origin before applying the projection transformation. Another is to transform the object’s origin by the model-view and (perspective) projection matrices, then change the projection to orthographic, un-project the position, and render the object.

Thanks for the ideas. I will have to digest them. My brain has been swimming lately with matrices, quaternions, GLSL, etc.

What I am doing right now is computing a scale factor to scale the object (on the modelview matrix) prior to rendering. I am computing the object’s distance from the origin in the XY plane (my up is the Z axis) and using the inverse of that distance as my scale factor to somewhat offset the perspective divide that takes place later. A little cheesy but it is about all I can handle right now. Next I was going to try to figure out the depth of my object instead of using the XY plane distance. And then after that I was going to figure out if I can linearize gl_Position.z so the object does not get enormous near the near plane.

I really appreciate the information available in this forum. I have been working with OpenGL for probably 15 years or so and there is still so much to learn.