0

I'm doing 3D perspective projection in OpenGL (webgl), doing it myself with uniform-matrices. Everthing is working fine, but I have an aspect ration of 3:2 (600px x 400px) and this distorts all geometry rendered.

In 2D I used to fix this in the model matrix by dividing x and y through 1 / width and 1 / height respectively.

Now I also have z to worry about and I am pretty clueless how / where to transform z to not distort on my 3:2 aspect ratio.

The model matrix does not seem to offer any opportunity to do this and I don't know where / what to do in the projection matrix.

Edit: Projection Matrix:

@_pMatrix = [  
  1, 0.0, 0.0, 0.0,  
  0.0, 1, 0.0, 0.0,  
  0.0, 0.0, -(f + n) / (f - n), -1,  
  0.0, 0.0, -2.0 * n * f / (f - n), 0.0  
]  

Column major order

Edit 2: Weird distortions on n < 1 img

elfeck
  • 385
  • 1
  • 8
  • Can you show how you're setting up your projection matrix? That's where you should define the viewing volume. And aspect ratio really doesn't apply to Z-coordinates as it's a function of the 2D viewport where there is no Z-coordinate (or rather, a uniform Z-coordinate). – beaker Nov 04 '14 at 17:34

1 Answers1

1

You're missing the *left*, *right*, *top*, *bottom* in your projection matrix.

 2*n      
-----     0       0        0
 r-l

         2*n
  0     -----     0        0
         t-b

 r+l     t+b    -(f+n)
-----   -----   ------    -1
 r-l     t-b     f-n

                -2*f*n     0
  0       0     ------
                 f-n

If you define (r-l)/(t-b) = 3/2 such that the viewing volume is the appropriate size for your model, then you should be set.

Here are some slides describing the various projection matrices and how they're derived: http://www.cs.unm.edu/~angel/CS433/LECTURES/CS433_17.pdf

They're by Edward Angel, the author of Interactive Computer Graphics, which is where I got this matrix. Unfortunately the OpenGL Red Book doesn't seem to work through the math at all.

beaker
  • 16,331
  • 3
  • 32
  • 49
  • I've seen that done but was always confused how / why this works. Can I choose l, r, t, b arbitrary as long as your equation holds? If I do `2 * n / (r- l)` I downscale stuff towards 0 as n is very small (0.001). Why do I need the `n` there anyway? – elfeck Nov 04 '14 at 18:18
  • I'm still looking for a good resource for the derivation of the matrix. I'll see what I can find and get back to you. – beaker Nov 04 '14 at 18:18
  • As I said, you need to make sure that your model, or whatever you want visible, can fit in the resulting frustum. The old OpenGL `gluPerspective` defined it using the field of view in the y direction and aspect ratio, which was translated to parameters appropriate to `glFrustum`. – beaker Nov 04 '14 at 18:23
  • okay I see. I'm kind of new to this projection stuff so sorry you need to hold my hand so much. Let's say I want a 300x300(x300) px cube to be visible. What are reasonable choices? If it is too much trial-and-error I will try it myself first. If you have a quick answer I would be thankful – elfeck Nov 04 '14 at 18:29
  • 1
    Try setting `l=-1.5, r=1.5`, `b=-1.0, t=1.0` and `n=1, f=10`. Then draw a `1x1x1` cube centered at `z=2`. That should get you pretty close. – beaker Nov 04 '14 at 18:44
  • Okay that works! I tried lowering `n` because 1 is clipping way to soon as I "approach" the cube with the camera. But as soon as `n < 1` the results get very distorted when rotating the cube. Edited main post for image. – elfeck Nov 04 '14 at 18:52
  • 1
    You need to use a bigger model farther away then. Using very small values for `near` (which is actually the focal length of an idealized pinhole camera) just causes weirdness. – beaker Nov 04 '14 at 19:00
  • Okay that kind of works. I think this specific issue is resolved, thank you _very_ much! There now are a bunch of different issues but I think this thread is finished. – elfeck Nov 04 '14 at 19:10