By default, the eye an the projection reference point PRP are in (0,0,0). I can change the eye position with gluLookAt(), but how can I change the PRP (i.e., the convergence position for a set of parallel lines) for a perspective projection in OpenGL?
2 Answers
Eye position, projection reference point PRP, camera center, or projection center are all just different words for the same thing.
gluLookAt() applied to the GL_MODELVIEW matrix works for both, parallel and perspective projection.
You can choose between parallel and perspective projection by setting up the GL_PROJECTION matrix. For perspective projection this can be done using the gluPerspective() function.
Creating a perspective projection matrix in OpenGL
Edit: (after revised question)
If the PRP is not at the eye position, you can not use gluPerspective(). Instead you have to create your own GL_PROJECTION matrix. Following the formula that you have now provided, this results in the 4 x 4 matrix:
$$\mathtt{A} =\begin{bmatrix} z_c-z_{pp} & 0 & -x_c & x_c \cdot z_{pp}\\ 0 & z_c-z_{pp} & -y_c & y_c \cdot z_{pp} \\ 0 & 0 & \frac{\mathrm{far}+\mathrm{near}}{\mathrm{near}-\mathrm{far}} & \frac{2 \cdot \mathrm{far} \cdot \mathrm{near}}{\mathrm{near}-\mathrm{far}} \\ 0 & 0 & -1 & z_c \end{bmatrix} $$
I have done a quick OpenGL/WebGL rendering test with the GSN Composer. Follow the link and move the mouse over the render output to change $x_c$ and $y_c$ of the projection reference point $(x_c, y_c, z_c)$:
-
$\begingroup$ Thank you. I have added a figure to show that the PRP is the 3D point that corresponds to the 2D vanishing point $\endgroup$– FreemanDec 24, 2017 at 19:37
-
$\begingroup$ Thanks for the figure. It seems as if I have understand you correctly. Use a combination of gluLookAt() and gluPerspective() to achieve the desired projection and position change of the camera. 2D vanishing points are something else: Parallel lines in 3D do not intersect - but after projection in the camera plane the projected lines might intersect. The intersection point in 2D is called "vanishing point". It is possible to infer the projection properties and rotation of a camera from vanishing points and when I first have read your question I thought you were maybe interested in this. $\endgroup$– NodeCodeJan 2, 2018 at 14:56
-
$\begingroup$ Thank you for answering. I don't want to change the vanishing point of parallel lines in the 2D projection, but the PRP of the perspective projection matrix. I have added another figure indicating that the eye (origin of the view coordinate) does not change, but the position of the PRP. glLookAt() enables to move the eye, but not the PRP (khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluLookAt.xml), which is the parameter that I want to change. You can find this general model in "Computer Graphics with OpenGL 4th ed", page 322. $\endgroup$– FreemanJan 5, 2018 at 11:21
-
$\begingroup$ Okay, I had a look at the book and now it is clear what you want. I have edited my answer accordingly. Sorry, I did not get it earlier. $\endgroup$– NodeCodeJan 5, 2018 at 21:57
If you are talking about an oblique perspective projection in which the line joining the eye and center of the projection plane is not perpendicular to the plane like here (upper left),
This can be generated by the glFrustum()
call. Normally when you describe perspective projection they set
left = -right
bottom = -top
so that these are centered around the Z-axis. In order to generate an oblique projection you can use the above mentioned method which takes input the coordinates for left, right, top, bottom, near and far planes.
The other way around is to build your own custom projection matrix, and load it directly. The matrix should be stored as an array
GLfloat mat[16] = {...}
GlLoadMatrix(mat)
-
$\begingroup$ I have added another figure indicating that the eye (origin of the view coordinate) does not change, but the position of the PRP. $\endgroup$– FreemanJan 5, 2018 at 11:20