PDA

View Full Version : Ok, got a wierd one involving Perspective Correction.



deathshadow
04-04-2004, 01:58 PM
I'm kind of new to GL and these boards, but not to 3d since I did some stuff 7-8 years ago by hand... and I have an odd question resulting from an interesting situation.

What I'm doing is trying to render all 360 degrees of vision into a single strip at the top of the screen. I was thinking easy, just render it as three 120 degree wide projections.

Here's the problem, if I turn the viewpoint as objects reach the edge of a projection they get bigger despite their distance not changing (kind of a fish-eye effect). In an old-style hand written 3d I would simply apply an inverse-sin to the z to fix this... How would I set openGL up to do this? I want the object's points to have the same Z adjustment to X and Y regardless of the objects distance.

Ideally I'd like it to:

Screen_Y= Y / actual distance
Screen_X= angle to(x,z)

Am I going to have to switch to Orthographic 2d Projection and do the math by hand, or is openGL capable of doing this for me? I actually have the math for doing this already written, but doing it by hand with a 3d landscape is abysmally slow; getting worse with detailed models in said landscape. (let's face it, calling Arctan(x/z) is not the fastest way of doing things)

dorbie
04-04-2004, 03:35 PM
This is quite normal. Each frustum has a tan theta distribution of pixels, and your strip wants an linear theta horizontally and the vertical axis to equal elevation.

You could use more fursta with small fields of view but this will only reduce the problem not eliminate it unless you have a LOT of frusta. Alternatively you could perform some distortion correction on the channels you render to the strip.

You would perform the distortion correction be copying (or rendering) the three to a texture then applying the textures to a mesh of triangles along the horizontal strip. This mesh or the texture coordinates would include the apropriate correction to linearize the angles.

You need to understand why what you have isn't working first. To help you with this I suggest you draw some rings around the eye at different heights representing constant elevation angle, and draw some vertical lines at regular angles representing constant azimuth, this will help you see the scalloping and spacing effect so you might understand why you are seeing the non linearity.

Alternatively draw a circle on a piece of paper. Then draw an isosceles triangle in the middle where each edge forms a chord on the circle.

Now on one of the segments of the circle trace points of equal angle back to the center of teh circle, and note where they intersect the chord. The spacing on teh circle is constant but the spacing on the chord is different. This is what happens in OpenGL projection onto the screen and why things on the edge of the screen appear larger unless the viewer looks at the screen from the real world equivalent of the center of the circle.

deathshadow
04-04-2004, 04:11 PM
Yeah, I figured as much, just wanted to double check I wasn't missing an option. Kind of odd you can't change said theta angle, but how often would what I'm trying to do come up? I actually had coded something close to your suggestion to illustrate said projection effects already to verify my suspicions.

I'm going the sx=arctan(x/z) and sy=y/sqrt(x^2+z^2) route in 2d ortho... Actually, I'm using lookup tables since I only need screenwidth accuracy for the Arctan and Zbuffer accuracy for the sqrt... Not sure how it will function once I start mixing textures into the equation, but I'm sure I'll find out.

Kind of an odd way to calculate a 3d projection, using the x,z angle for one axis...

Thanks for the response. As I go I'm sure I'll have more questions; I'm picking things up pretty quick, but I haven't programmed in four to five years so...

howie
04-04-2004, 06:23 PM
Try setting a tighter angle for your view fustrum. You'll have to back out a little further, but the fish eye look will be a lot less.

gluPerspective( 40.0f, ...

or

gluPerspective( 30.0f, ...

or

gluPerspective( 20.0f, ...