Monday, July 25, 2022

Primer: Understanding View space, Perspective and Orthographic Projections

Overview
So far our camera was in a fixed position and transformations happened in object space.  In this post we will  look at the larger picture.

Details
As shown in the diagram below, a 3D object in a scene starts off from object space. Model transformation places it in the world space using a model matrix.  Based on the camera position the entire world is transformed into Camera space or view space. This is called view transform. This is done using viewing matrix. It is later moved to screen space using Projection matrix.


So far in our examples, camera is located at the origin and view and projection matrixes are not computed; instead identity matrix is used.  Next we will try to move around the camera and understand different type of projections.

Model Matrix
Model Matrix is responsible for moving 3D objects  from object space to world space. The affine transformation discussed in Lesson 08 are applied.

View Matrix
When the hypothetical camera position is changed, the whole world is transformed around it using view matrix. The internals is as described below (courtesy : learnopengl.com).
 


1. Camera position
The camera position or eye at (0,0,2) is a vector in world space.

2. Camera direction vector
The  Camera direction vector is the direction at which the camera is pointing at. This is computed from the scene's origin or center in this case it's  (0,0,0). Subtracting the camera position vector from the scene's origin vector thus results in the direction vector. This must always point to +Z axis by RHS convention.
Therefore normalize((0,0,2) - (0,0,0)) = (0,0,1)

3. World up vector
The up vector (0,1,0) points to worlds Y axis. This may not be always the case.

4. Right axis vector
The right axis vector represents the positive x-axis of the camera space. This is obtained by doing a cross product on the up vector and the camera direction vector from step 2. 
Therefore cross((0,1,0) -  (0,0,1)) = (1,0,0)

5. Up axis vector
The Up axis vector points to camera's positive y-axis. It's computed by the cross product of the right and direction vector.
Therefore cross((0,0,1) - (1,0,0)) = (0,1,0)

The view matrix is computed as below from glm as below.
mat4 lookAt(vec3 const& eye, vec3 const& center, vec3 const& up)

NameDescription
eyeThe 3D coordinates defining exactly where the camera is located in world space.
centerThe 3D coordinates representing the point in the world that the camera is looking at.
up  A directional hint (usually ([0, 1, 0])) indicating which way is "up" in the world, ensuring the camera doesn't roll or tilt improperly.

Example
In the example below, the camera position or eye vector is placed in front of the cube at (0,0,5). Center is located at (0,0,0) and up vector is (0,1,0).



As mentioned earlier, the World up vector need not be always (0,1,0).
For example,  if  the camera is moved on top of the cube say (0, 5, 0), we will be looking at the  top of the cube.  The eye is (0,5,0), center is (0,0.0) and up is (1, 0, 0) not (0,1,0).



Projections
The final matrix is projection matrix. There are two types of projections
Orthographic and Perspective. The traits are as below.


The following shows another view with the view frustum. A view frustum is a rectangular box that confines the image rendered to be shown on the screen. 


The volume or the frustum is defined by the left, right, top, bottom, near and far plane values. 

perspective
The perspective projection is computed in glm as below. In Perspective projection, the frustum appears as a truncated pyramid. 
perspective(float fovy, float aspect, float zNear, float zFar)

NameDescription
fovy Field of View (FOV) or zoom factor 
aspect Aspect ratio of the viewport. i.e., width/height.
ZNear  Distance from the camera to the near plane
ZFar Distance from the camera to the far plane

Example:
perspective(45.0, 1.84, 1.0, 100.0)
The screenshot below shows the perspective projection of the colored cube rotated 20 degree pitch and 20 degree yaw.


ortho
The orthographic projection is computed in glm as below. In orthographic projection, the frustum appears as a cube. 
ortho(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax)

NameDescription
xminleft of the view frustum
xmax right of the view frustum
ymintop of the view frustum
ymax bottom of the view frustum
ZMin distance from the camera to the near plane
ZMax distance from the camera to the far plane

Example:
ortho(-1.84, 1.84, -1.0, 1.0, 1.0, 100.0); 
Note that the aspect ratio is 1.84.
The screenshot below shows the orthographic  projection of the colored cube rotated 20 degree pitch and 20 degree yaw.

Unproject
Sometimes it's useful to capture x,y,z coordinates in the object space based on the mouse cursor position. UnProject() accomplishes this.  The X,Y coordinates from the mouse cursor position and Z value from the depth buffer is used to compute the window coordinates. Later this is passed to glm unProject() along with Model, View and Projection Matrix, to get the co ordinates in world space.

wstring Unproject(const mat4& ProjectionMat)

NameDescription
ProjectionMatThe current Projection matrix of the mouse coordinate.

Example:
In the below, the red dot in the cube represents mouse cursor position  
x = 353 y = 168 and depth buffer Z = 0.79


Using  Model, View, and Perspective Projection matrices, the world space coordinate is calculated as
0.22, 0.12, 0.43.


No comments:

Post a Comment