## OpenGl and perspective matrices

### OpenGl and perspective matrices

Hello,

I'm using OpenGL for my perspective projection, but there's something I can't
understand. Here is the perspective matrix, as it is computed after a call to
glFrustum().
So if you call glFrustum(l, r, b, t, n, f), the perspective matrix is :

_                         _
|     2n       r+l          |
|    -----  0  ---      0   |
|     r-l      r-l          |
|                           |
|        2n    t+b          |
R = |    0  ----   ---      0   |
|        t-b   t-b          |
|                           |
|             -(f+n)  -2fn  |
|    0    0   ------  ----  |
|              f-n     f-n  |
|                           |
|    0    0    -1      0    |
|_                         _|

(taken from the OpenGL programming guide, and the Mesa source code)

Okay, so now, let's take a concrete example.
If I call glFrustum(-3, 3, -2, 2, 1, 10), then the following perspective matrix
is generated :

[ 0.3333   0    0       0   ]
[    0     0    0       0   ]
R = [    0     0  -1.222  2.222 ]
[    0     0    -1      0   ]

Now, let's take the point (-3, 2, 10, 1), and let's apply the perspective matrix
on it. The result is (-1, 1, -10, -10). Until now, all is fine.

But if now I take another point (-3, 2, 50, 1), then I obtain the same x and y
coordinates as the previous example ! (i.e. x = -1 and y = 1).
Normally, since the second point is farther than the first one, the x and y
coordinates should not be the same !! They should be smaller !
But as we can see in the perspective matrix, all the matrix elements that could
be influenced by the value of the z coordinate are set to 0, so you can set the
z coordinate to any value, it won't change anything !! (which is the opposite of
the perspective transformation method, where the z coordinate is very
important).

So could someone tell me what's going wrong, please ?

It's common to have r == -l and b == -t, no ? But in this case, many matrix
elements become equal to 0, generating the problem I described above...

Thank you very much for your precious help ! (and please send a copy of your
replies to my personal email address, since my news server discards a lot of
messages).

Best regards,

*****************************************************
*                                                   *

*                                                   *
* http://www.dtr.fr/homepage/gcornu/collector.html  *
*                                                   *
*****************************************************

### OpenGl and perspective matrices

Quote:> I'm using OpenGL for my perspective projection, but there's something I can't
> understand. Here is the perspective matrix, as it is computed after a call to
> glFrustum().
> So if you call glFrustum(l, r, b, t, n, f), the perspective matrix is :
> ...
> Now, let's take the point (-3, 2, 10, 1), and let's apply the perspective matrix
> on it. The result is (-1, 1, -10, -10). Until now, all is fine.

> But if now I take another point (-3, 2, 50, 1), then I obtain the same x and y
> coordinates as the previous example ! (i.e. x = -1 and y = 1).
> Normally, since the second point is farther than the first one, the x and y
> coordinates should not be the same !! They should be smaller !
> But as we can see in the perspective matrix, all the matrix elements that could
> be influenced by the value of the z coordinate are set to 0, so you can set the
> z coordinate to any value, it won't change anything !! (which is the opposite of
> the perspective transformation method, where the z coordinate is very
> important).

> So could someone tell me what's going wrong, please ?

I didn't work through your example for myself but suspect that you're just
forgetting the "divide by W" step.

Using your first result of (-1, 1, 10, -10), you should divide all components
by -10:

(-1/-10, 1/-10, 10/-10, -10/-10)

which is
(0.1, -0.1, -1, 1)

The divide by W step is what accomplishes the perspective effect.  This is
a separate step because dividing by W can't be expressed with a transformation
matrix.

-Brian

--------------------------------------------------------------------
Brian Paul   Avid Technology   Madison, WI

### OpenGl and perspective matrices

Hi,

You didn't quite carry the computation to completion.  After
the point is transformed by the projection matrix, resulting in the
new homogenous coordinate, ( x', y', z', w' ), the next step
is to perform the "perspective divide",  where you divide each
element by w', yielding

x'    y'    z'
( ----, ----, ---- )
w'    w'    w'

This coordinate lives in what's called "normalized device coordinates",
which is a ( generally described as ) a cube with corners at +/- 1
for each coordinate.

The perspective divide step is the part which actually causes
the x's and y's to decrease the farther from the eyepoint.

Hope that helps.

Thanx,
Dave

---------------------------------------------------------------------

Silicon Graphics, Inc.                            (650) 933-4899

### OpenGl and perspective matrices

: Okay, so now, let's take a concrete example.
: If I call glFrustum(-3, 3, -2, 2, 1, 10), then the following perspective matrix
: is generated :

:     [ 0.3333   0    0       0   ]
:     [    0     0    0       0   ]
: R = [    0     0  -1.222  2.222 ]
:     [    0     0    -1      0   ]

I believe you have your top and bottom params reversed, thus giving
you 0.5 instead of 0.0 at position [1][1] in the matrix. However, it's
a moot point, since the following calculations appear to have used the
correct matrix.

: Now, let's take the point (-3, 2, 10, 1), and let's apply the perspective matrix
: on it. The result is (-1, 1, -10, -10). Until now, all is fine.

: But if now I take another point (-3, 2, 50, 1), then I obtain the same x and y
: coordinates as the previous example ! (i.e. x = -1 and y = 1).
: Normally, since the second point is farther than the first one, the x and y
: coordinates should not be the same !! They should be smaller !

You have not multiplied by 1/q yet.

For the first point, resulting XYZ values are:
( -1 / -10,  1 / -10,  -10 / -10 )

For the second point, resulting XYZ values are:
( -1 / -50,  1 / -50,  -58.88 / -50 )

I hope that explains things.
--
-Paul                Hewlett Packard Graphics Products Lab

"Technology can be used for good or evil. Please use only for good."

### OpenGl and perspective matrices

: You have not multiplied by 1/q yet.

Ooops. Of course I meant 1/w, not 1/q. (I've been working with texture
mapping too much lately.)
--
-Paul                Hewlett Packard Graphics Products Lab

"Technology can be used for good or evil. Please use only for good."