How do reverse perspective with OpenGL?

962 Views Asked by At

I'm looking for a way to do reverse perspective with OpenGL and C++. For now, I'm using glFrustum to have a classic perspective, but I would like to know if a reverse pespective as presented here (https://en.wikipedia.org/wiki/Reverse_perspective and below) is possible ? If not, is there any other way with OpenGL to do this ?

enter image description here

1

There are 1 best solutions below

0
Brett Hale On

This question really intrigued me. I'm not entirely convinced that what I'm going to refer to now as 'Byzantine perspective' can be accommodated by a transform analogous to that provided by (pre-core profile) glFrustum. I have done some work on it though, inspired by derivations in Computer Graphics: Principles and Practice (2nd Ed), and the formulation for the OpenGL CCS / NDCS.

Unfortunately, the original S.O. site doesn't allow for embedded LaTeX, so the matrices will not be pretty. Consider this answer a work in progress


So far, I've derived the matrix transform resulting in what is sometimes referred to as the 'normalized frustum'. The far plane at Z = -1, the near plane at Z = - N / F, and the R, L, T, B planes having unit slope. (this would be very clear given a good diagram)

[ 2N / (R - L)      0        (R + L) / (R - L)     0     ]
[       0      2N / (T - B)  (T + B) / (T - B)     0     ]
[       0           0                1             0     ]
[       0           0                0             F     ]

Call this matrix: [F.p]. For any point: P = (x, y, - N, 1)^T on the near plane, it's easy to demonstrate that the transformed homogeneous point lies on the Z = - N / F plane. (Note: ^T is the 'transpose' operator to make it clear that this is in fact a column vector.)

Likewise, given a point: P = (x, y, - F, 1)^T on the far plane, the transformed homogeneous point lines on the Z = -1 plane.


A Byzantine perspective requires another constraint - we'll use the variable D, where Z = - D is a point analogous to the 'eye' at Z = 0, or the 'projection reference point' (PRP).

As you have already gathered from the image you've provided, parallel lines converge at Z = - D, rather than at the 'eye'. You don't want the image from the the point of convergence however. You want to visualise the effect from the 'front'. The question is - can we construct an OpenGL matrix similar to that provided by glFrustum which yields a Byzantine perspective? And can it be made to fit within a GL pipeline?

What I've derived so far, is the 'normalized Byzantine frustum'. Again, the far plane is at Z = -1, the near plane at Z = - N / F, and R, L, T, B planes have unit slope - albeit the negative slope of the regular frustum. (again a clear picture would be worth a thousand words here)

[ 2N / (R - L)      0        (R + L) / (R - L)     0     ]
[       0      2N / (T - B)  (T + B) / (T - B)     0     ]
[       0           0              N / F           0     ]
[       0           0                0             N     ]

Call this matrix: [F.b]. The X,Y coordinate transforms are identical, but the Z,W component transforms differ. This is somewhat intuitive given that this is, in a sense, a 'reverse' of the orthodox view volume.

Again, given a point: P = (x, y, - N, 1)^T on the near plane, the transformed homogeneous point lies on the Z = - N / F plane, and the homogeneous transform of a point: P = (x, y, - F, 1)^T on the far plane lies on the Z = -1 plane.


Given the similarities in the matrices, and the fact that only simple perspective transforms (and a few trivial scaling and translation matrices) are required to yield parallel projection matrices that conform to OpenGL clip coordinate space (CCS), and its NDCS projection, it seems likely that an OpenGL 'Byzantine' projection could be made to work. I just need more time to work on it...