teaching machines

Deriving the View Matrix

August 10, 2020 by . Filed under graphics, public.

Computer graphics is less about knowing when to apply algorithms and more about knowing where. There are many possible wheres. Our 3D models are born in model space. To situate models in the virtual world, their model space coordinates are transformed into world space. Many lighting algorithms are applied in camera or eye space. From eye space, we pass on into clip space, normalized device space, and screen space.

In this post, we’ll restrict our discussion to the transformation that turns world space coordinates into eye space coordinates. We’ll call the matrix that performs this transformation the view matrix $\mathbf{V}$. What does $\mathbf{V}$ look like? When I first learned computer graphics, the structure of the view matrix was just handed down to me from on high. But you can only do so much with someone else’s magic.

We have the following four constraints to help us figure out what $\mathbf{V}$ looks like.

Let’s make our constraints a bit more precise by considering how the transformation turns world space coordinates into eye space coordinates.

We can put these four vector multiplications together into a single matrix-matrix multiplication.

$$\mathbf{V} \times \begin{bmatrix} r_x & u_x & f_x & p_x \\r_y & u_y & f_y & p_y \\r_z & u_z & f_z & p_z \\ 0 & 0 & 0 & 1\end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 & 0 \\0 & 1 & 0 & 0 \\0 & 0 & 1 & 0 \\0 & 0 & 0 & 1\end{bmatrix}$$

Notice the structure of our matrix of viewer parameters. It is the product of a translation matrix $\mathbf{T}$ and a rotation matrix $\mathbf{R}$. Additionally, the right-hand side is the identity matrix.

$$\begin{array}{rcl}\mathbf{T} &=& \begin{bmatrix}1 & 0 & 0 & p_x \\0 & 1 & 0 & p_y \\0 & 0 & 1 & p_z \\0 & 0 & 0 & 1 \end{bmatrix} \\\mathbf{R} &=& \begin{bmatrix}r_x & u_x & f_x & 0 \\r_y & u_y & f_y & 0 \\r_z & u_z & f_z & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \\\mathbf{V} \times (\mathbf{T} \times \mathbf{R}) &=& \mathbf{I} \\\end{array}$$

Let’s solve for $\mathbf{V}$. We pull a few identities out of our hat to make this happen. First, multiplying a matrix by its inverse turns it into the identity matrix. Second, multiplying a matrix by the identity yields the original matrix. Third, the inverse of a product is the product of its operands’ inverses, commuted.

$$\begin{array}{rcl}\mathbf{V} \times (\mathbf{T} \times \mathbf{R}) \times (\mathbf{T} \times \mathbf{R})^{-1} &=& \mathbf{I} \times (\mathbf{T} \times \mathbf{R})^{-1} \\\mathbf{V} &=& (\mathbf{T} \times \mathbf{R})^{-1} \\\mathbf{V} &=& \mathbf{R}^{-1} \times \mathbf{T}^{-1} \\\end{array}$$

In separating our parameter matrix into $\mathbf{R}$ and $\mathbf{T}$, we have made finding the inverses easier. The job of the inverse of a transformation is to undo the transformation. The inverse of a translation, then, is just a translation by the negative offsets. The inverse of a rotation matrix “unrotates,” and the inverse just happens to be the transpose—though I do not find this obvious. Therefore, we have the following construction for $\mathbf{V}$:

$$\begin{array}{rcl}\mathbf{V} &=& \mathbf{R}^\textrm{T} \times \mathbf{T}^{-1} \\\mathbf{V} &=& \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}\end{array}$$

One could also arrive at this matrix by thinking of it as a translation of the viewer to the origin and then a rotation the viewer’s frame to align with the standard axes. I prefer the construction above because I don’t trust myself to understand rotation matrices.