Question

I am attempting to work in LWJGL to display a simple quad using my own matrices. I've been looking around for awhile and have found a few perspective matrix implementations, these two in particular:

[cot(fov/2)/a 0          0                  0]
[0            cot(fov/2) 0                  0]
[0            0          -f/(f-n)          -1]
[0            0          -f*n/(f-n)         0]

and:

[cot(fov/2)/a 0          0                      0]
[0            cot(fov/2) 0                      0]
[0            0          -(f+n)/(f-n)          -1]
[0            0          -(2*f*n)/(f-n)         0]

Both of these provide the same effect, as expected (got them from here and here, respectively). The issue is in my understanding of how multiplying this by the modelview matrix, then a vertex, then dividing each x, y, and z value by its w value gives a screen coordinate. More specifically, if I multiply either of these by the modelview matrix then by a vertex (10, 10, 0, 1), it gives a w=0. That in itself is a big smack in the face. I conclude either the matrices are wrong, or I am missing something completely. In my actual test program, the vertices don't even end up on screen even though the camera position at (0,0,0) and no rotation would make it so. I even have tried many different z values, positive and negative, to see if it was just a clipping plane. Am I missing something here?

EDIT: After a lot of checking over, I've narrowed down the problem I am facing. The biggest issue is that the z-axis does not appear to be remapped to the range I specify (n to f). Any object just zooms in or out a little bit when I translate it along the z-axis then pops out of existence as it moves past the range [-1, 1]. I think this is also making me more confused. I set my far plane to 100 and my near to 0.1, and it behaves like anything but.

Was it helpful?

Solution

Both of these provide the same effect, as expected

While the second projection matrix form is very standard, the first one gives a different effect. If you have z==1 and w==0, the projection will be:

Matrix 1: -f/(f-n) / -f*n/(f-n) = f / f*n = 1 / n

Matrix 2: -(f+n)/(f-n) / -(2*f*n)/(f-n) = (f+n) / (2*f2n)

The result is clearly different. You should always use the second form.

if I multiply either of these by the modelview matrix then by a vertex (10, 10, 0, 1), it gives a w=0. That in itself is a big smack in the face

For a focal length d the projection is computed as (ignoring aspect ratio):

x'= d*x/z = x / w
y'= d*y/z = y / w

where

w = z / d

If you have z==0 this means that you want to project a point that is already in the eye and only points beyond d are visible. In practice this point will be clipped because z is not within the range n (near) and f (far) (n is expected as a positive constant)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top