OpenGL Matrices

See also my notes on row-major and column-major conventions.

Types of matrices

There are four types of matrices we are concerned with in most OpenGL apps.

  1. Scaling – make bigger or smaller
  2. Translation – move
  3. Rotation – spin around.
  4. Projection – convert view-space (aka, camera space) coordinates to screen-space

By building and concatenating these types of matrices, we can create a single object (matrix) that performs all of these operations with a single (and fast on the GPU) matrix multiply.

Looking at 16 apparently-random floating point values in a 4×4 matrix can be confusing, we can simplify things a bit if we understand the meaning of each of the individual cells within the matrix.

Meaning

The matrix is really a collection of 4, 4-component vectors. Each vector describes a basis vector of the transformed coordinate system. For instance, in a native, untransformed 3D Cartesian space, we know that the three axis are represented by unit vectors in each direction.

\(
\dot{\vec{x}} = 1\hat{x} + 0\hat{y} + 0\hat{z} \\
\) \(
\dot{\vec{y}} = 0\hat{x} + 1\hat{y} + 0\hat{z} \\
\) \(
\dot{\vec{z}} = 0\hat{x} + 0\hat{y} + 1\hat{z} \\
\)

These can be conveniently represented by a 3×3 matrix and a vector:

\(
\begin{bmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1 \\
\end{bmatrix} *
\begin{bmatrix}
v_x \\
v_y \\
v_z \\
\end{bmatrix}
\)

Multiplying a three component (x,y,z) vector(aka Vector3) V by this matrix would give us a three-component vector \(v_1\),

\(
v^1_x = v_x * 1 + v_y * 0 + v_z * 0
\) \(
v^1_y = v_x * 0 + v_y * 1 + v_z * 0
\) \(
v^1_z = v_x * 0 + v_y * 0 + v_z * 1
\)

Note that this is the same as the dot product of \(v_1\) with each row of the matrix.

How to multiply a 4×4 matrix with a 4 component vector

\(
\begin{bmatrix}
a & b & c & d \\
e & f & g & h \\
i & j & k & l \\
m & n & o & p \\
\end{bmatrix}
\begin{bmatrix}
v_x \\
v_y \\
v_z \\
v_w \\
\end{bmatrix} =
\begin{bmatrix}
v_x * a + v_y * b + v_z * c + v_w * d \\
v_x * e + v_y * f + v_z * e + v_w * f \\
v_x * i + v_y * j + v_z * k + v_w * l \\
v_x * m + v_y * n + v_z * o + v_w * p \\
\end{bmatrix}
\)

Why we use 4×4 Matrices

Translation – we need a 4th row or column to store translation values. See the Translation Matrix page for details.