1

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

  • Of course it's possible. It's still a linear transformation, so devising a custom projection matrix is all you need. But I suspect that you can go even simpler (if you're using legacy `glFrustum` &company): reverse the depth buffer operation so that it only lets the farther objects pass, and use the usual projection matrix with depth coordinate reversed. – Ruslan Mar 24 '20 at 08:34
  • Just an idea, not sure if this is exactly the right method. But it looks very similar to the method of creating shadows: https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping The idea is that creating the reversed perspective is identical to looking from other point and generating a texture as result. Then apply the texture to your surface where you would like to draw it. Also see the shadows in WebGL: https://webglfundamentals.org/webgl/lessons/webgl-shadows.html – armagedescu Mar 24 '20 at 08:46
  • I'm not sure whether this is possible to do with adjusting the projection matrix. As I understand this, you need to multiply by `z`, instead of dividing by `z` at the projection stage. But I think that you can do this by using a custom vertex shader, which calculates `w = 1/z` instead of the usual `w = z`. – geza Mar 24 '20 at 08:54

1 Answers1

3

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...

Brett Hale
  • 21,653
  • 2
  • 61
  • 90