Anamorphosis?

Hi,

I’m interested in generating anamorphosis images like this from a 3D model:

http://www.rense.com/1.imagesH/artt5.jpg

So the idea would be to take a standard model-view/projection transform and alter it to achieve this effect. The result would be, for example, that looking at the final projection in 2D straight on would show the 3D objects stretched out but looking at it at some extreme angle would show them undistorted and in perspective.

Conceptually it seems like I want to do a perspective transformation but instead of via a frustum with a front face perpendicular to the viewer, it would be slanted at some angles on the x and y axes (assuming a view down the z axis).

It doesn’t seem like this is terribly innovative but I can’t seem to find any examples of people doing this. I’m quite new to this stuff so maybe it’s called something other than anamorphosis?

I did some math and I’ve come up with the equations for the projection in a simple case of just tilting the top edge of the front of the frustum (or whatever that volume is called after such an operation) away from the viewer. I’d like to add it to the list of transformations that OpenGL is going to do but I’m having trouble converting them to matrix form. They look like this:

x’ = x * n * tan(a) / ( y + z * tan(a) )
y’ = n * tan(a) / ( sin(a) * ( y / z + tan(a) )
z’ = n * tan(a) / ( y / z + tan(a) )

where the viewer is at (0,0,0) looking down the positive z-axis. n is where the project plane crosses the z axis and a is the tilt or the angle between this plane and the z-axis. Can anyone give me a pointer as to how to convert this to matrix form? It’s looking non-linear to me so I’m kind of suspicious if it’s possible?

Or if anyone can think of a better approach. Maybe it would be better to do some 3D-to-3D transformation that adds distortion there and then do a normal perspective transformation? Or maybe the only way is to take the undistorted 2D projection and map that in some distorted way as a texture onto the slanted projection plane? That seems like it would get pixelated though.

Thanks for any ideas or anything that would shoot down my idea and thus save me some time.

The technique in the image you linked to would be called “projective texturing” (it is only linear, no need for atan for example). You should find a lot more of stuff with that.
Very similar to shadow mapping for example.

For non-linear projections (cylindrical, spherical, etc) look at this thread, it is somewhat similar :
http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=276310

What you need is a ray-caster. What you are trying to do is forward projection, which ‘may’ be possible, but definitely harder.

Here is what you want to do:

Imagine you have a camera set-up to look at a 3D world. Take a picture. Now remove the 3D world, and place a plane aligned to the camera in-front of it. Paste the picture on this plane as a texture. From the point of view of the camera, it still looks like a 3D scene. Rotate the camera, and you begin to see its just a 2D plane.

That was the simplest case. To make it more like an anamorphosis, you want the final texture to be applied to a different 3D scene, or some planes that are not aligned to the camera. Yet, the texture, when mapped, has to look like the 3D scene from that particular point of view. So, lets imagine instead of replacing the world with a plane, lets replace it with two planes, that form a ‘v’ like the corner of a box (room) with the corner right in-front of the camera.

If you paste your texture as-is, the middle of the texture (the corner) will be shrunk due to those parts being away from the camera. So, what you want to do, is depending on the distance from the camera, apply an inverse perspective projection to your texture. The texture will look stretched, and awful, but when applied to the scene (the corner) it will look just like the original scene after the transformation.

Edit: Yes, just saw ZBuffers reply, its called Projective Texture Mapping.

Yep, that looks like what I was looking for. Thanks!