Imagine having a mixed group of 3D objects contained within a sphere, and your goal is to create a cylindrical equal-area projection of the entire scene. Using OpenGL, you might think to stitch together multiple render target textures (4 to be exact) from rotating a camera about the central axis, and then correct for radial distortion in a post-processing shader since you are projecting onto a plane instead of a cylinder. Ideally, you'd be able to sweep the camera's frustum through the entire volume of the sphere without any overlap, and such that each render fills the entire pixel space of the rectangular texture (as cylindrical projections do).
So, just for clarity, here is a visualization of the spherical scene (which has objects contained within), and a camera frustum that spans PI / 2 about the Y-axis.
Notice that the 'far' plane is reduced to a line, which is collinear with the sphere's Y-axis. The white intersecting lines that form an "X" on the outer face of the frustum represent the camera's origin, or (0,0,0) in eye-space. This outer face is also the 'near' plane, located 0 Z-units away from the camera.
The idea is that the sphere's central axis projects rays outwards such that all rays travel parallel to the Y-plane (i.e., the plane having normal (0, 1, 0)), and each ray emanating from the sphere's origin intersects the sphere's surface at a perpendicular angle.
My question:
Naively, I think that an OpenGL projection matrix can do this -- as far as I understand, the projection I am going for here is linear and therefore possible? However, I can't seem to solve the equations properly:
lets
be the radius of the sphere.
So, in eye-space, from the camera's origin:In the OpenGL projection matrix:
- the left and right edge of the near plane are located at
-s
ands
units along the X-axis, respectively- the top and bottom edge of the near plane are located at
s
and-s
units along the Y-axis, respectively- the left and right edge of the far plane are co-located at
-s
units along the Z-axis (keep in mind that in eye-space, Z values are negative in front of the camera)
-w_c < x_c < w_c
x_n = x_c / w_c
Since the left and right frustum planes converge in front of the camera, I solved for an equation that maps my inputs to their expected outputs and concluded that:Which means that
x_n = x_e / (z_e + s)
x_c = x_e
andw_c = z_e + s
. This fills in two rows on my projection matrix:
---------- This is where I get stuck ----------
It's clear thaty_n
does not depend onx_e
orz_e
at all, and that its equation should be:This is akin to an orthographic projection. However, this introduces a conflict with the
y_n = y_e / s
w_c
I already solved for in thex_n
equation.
I derived my projection matrix above by following steps from this article, which succinctly explains the derivation of the perspective and orthographic projection matrices for OpenGL.
It appears that I may be encountering the limits of a linear transformation? If this indeed is non-linear, then I don't understand why and would appreciate an explanation :)
Since your projection require
y = sin(phi)
the mapping is non-linear.Theoretically, with a 4x4 matrices (together with homogeneous coordinates), you can describe affine transformations which is a bit more expressive than a linear transformation. Affine transformations have the form
a * x + b
where a and x are vectors and b is a scalar value. There is no way how can express trigonometric functions with that.