Shadow Map - View - Shadow Map - Shader Learning

Shadow Map

Shadow Map - View

Task

Calculate a new view matrix (also known as a light view matrix) that transforms the scene to the light source’s space. This allows us to see the scene as if we were looking directly from the light source.

Theory

The idea behind shadow maps is as follows: we additionally draw the scene from the light source point of view. The view for the shadow map is aligned with the light's local coordinate system. Everything that is visible is illuminated, the rest is in shadow.



To implement the algorithm we first need to figure out how to form a new view matrix having the direction vector F in a right-handed coordinate system (OpenGL is right-handed). Follow these steps:

  1. Normalize and flip the direction vector F, since the Z-axis must be pointing towards the camera in the right-handed coordinate system.


  1. Take up vector U in world space, it is typically (0, 1, 0).
  2. Compute the right vector R. The right vector R is perpendicular to the direction vector -F and the up vector U. You can compute it using the cross product: R = U x -F


  1. Compute the new Up vector. We know for sure that vectors -F and R are perpendicular, but we cannot guarantee that -F and U are perpendicular since their values were taken independently of each other. Therefore, we need to calculate a new vector U' that completes the orthogonal system: U' = -F x R.


  1. Create the View Matrix. The view matrix is a 4x4 matrix that combines the right, up, and direction vectors. It looks like this:

$ \begin{bmatrix} R_x & R_y & R_z & 0 \ U'_x & U'_y & U'_z & 0 \ -F_x & -F_y & -F_z & 0 \ 0 & 0 & 0 & 1 \ \end{bmatrix} $

  1. Add Translation. To translate an object from world space coordinates to view space coordinates, we must subtract the position of view P from the position of the object. This can be represented as a matrix:

$ \begin{bmatrix} 1 & 0 & 0 & -P_x \ 0 & 1 & 0 & -P_y \ 0 & 0 & 1 & -P_z \ 0 & 0 & 0 & 1 \ \end{bmatrix} $

We can add the translation to our view matrix by matrix multiplication:

$ \begin{bmatrix} R_x & R_y & R_z & 0 \ U'_x & U'_y & U'_z & 0 \ -F_x & -F_y & -F_z & 0 \ 0 & 0 & 0 & 1 \ \end{bmatrix}

\times

\begin{bmatrix} 1 & 0 & 0 & -P_x \ 0 & 1 & 0 & -P_y \ 0 & 0 & 1 & -P_z \ 0 & 0 & 0 & 1 \ \end{bmatrix} $

  1. If rendering system expects column-major matrices (like OpenGL), transpose the matrix.