2
$\begingroup$

I want to decompose projection matrices into near, far, top, bottom, left and right values to create a bounding box for view frustum. I used the formula described in this site Decompose the OpenGL projection matrix. This formula works for perspective which is created with frustum function (glFrustum). But it does not work for perspective which is created via perspective func (gluPerspective)

Frustum and perspective may create same perspective effect but generated matrices seems different. So it seems I can't use single formula to extract perspective parameters.

  1. Is there any proof of that decomposition formula, or does it always work?
  2. How do I decompose the matrix generated by perspective function into near, far, top, bottom, left and right values? Is there any formula which is already used in industry?

My implementations of ortho, frustum and perspetive is here: https://github.com/recp/cglm/blob/master/include/cglm/cam.h

$\endgroup$

1 Answer 1

0
$\begingroup$

Do you have any "input data" from which you constructed the matrix (like fov, near plane distance, etc.)? Or is the matrix itself the only data you have?

EDIT: Ok, so if you want to know the size of the near plane while you have viewProj matrix available do this:

a) compute viewProj^-1

b) vertices of the near plane in clip-space have coordinates (in OpenGL): (-1, -1, -1, 1) (-1, 1, -1, 1) ( 1, -1, -1, 1) ( 1, 1, -1, 1)

and on the far plane: (-1, -1, 1, 1) (-1, 1, 1, 1) ( 1, -1, 1, 1) ( 1, 1, 1, 1)

It's a unit cube spanning (-1, -1, -1) and (1, 1, 1) coordinates with w=1

c) take each of those vertices, mutiply by viewProj^-1 and finally divide all resulting components by the w-component. That gives you the frustum's vertices in world space. From this you can easily find world space planes constraining the view frustum or the bounding box or whatever you like.

I think it's not possible to extract left/right/bottom/top/near/far from the matrix directly. But since you can compute the world space coordinates of frustum's corners (as shown above) you can easily find left/right/bottom/top/near/far.

$\endgroup$
6
  • $\begingroup$ yes the only data I have is matrix itself. Only matrices (world, view, proj, projView) are cached inside camera. $\endgroup$
    – recp
    Commented Nov 22, 2017 at 13:00
  • $\begingroup$ but this Decompose the OpenGL projection matrix works for glFrustum, maybe some similar formula can work for glPerspective, no way? I will try your steps (thanks), it also seems interesting and matching to my goal (get and convert view frustum coordinates to another view space (light's point of view) $\endgroup$
    – recp
    Commented Nov 22, 2017 at 13:52
  • $\begingroup$ That formula also works for getting near and far from glPerspective, only left, right, top and bottom need to be calculated. Maybe m00 (f / aspect) and m11 (f) relation could help to get aspectRatio. Then we will have aspectRatio, near and far, then maybe we could get the remain values, I will give a try $\endgroup$
    – recp
    Commented Nov 22, 2017 at 14:10
  • $\begingroup$ Well, I think it does not matter whether the matrix was created with glFrustum or gluPerspective. If the formula from the link you provided works "for glFrustum" it should equally well work "for gluPerspective". In fact, gluPerspective is built on top of glFrustum. gluPerspective simply "remaps" fov and aspect on left/right/top/bottom and calls glFrustum. $\endgroup$
    – maxest
    Commented Nov 22, 2017 at 14:19
  • $\begingroup$ My confusion was that some items used to decompose always is zero in glPerspective, maybe this doesn't change the result. I will compare same view frustum for both $\endgroup$
    – recp
    Commented Nov 22, 2017 at 14:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.