Math for Game Development and WebGL Part 6: Matrix Math Intro

What is a matrix?

A matrix is a rectangular array of numbers arranged in rows and columns:

$$\begin{bmatrix}
1 & 2\\
3 & 4
\end{bmatrix}$$

You may think, isn’t a vector also a rectangular array of numbers? Yes, you can also think of a vector as a matrix with one row or one column (row vs column does make a difference, but more on that later.

In fact, in mathematics you’ll often see vectors drawn like this:

$$\begin{bmatrix}
5\\
6
\end{bmatrix}$$

or like this:

$$\begin{bmatrix}
5 & 6
\end{bmatrix}$$

where 5 is x and 6 is y in our vector implementation.

A vector will never have multiple rows and columns though, only a matrix can have multiple rows and columns.

Vector Times Matrix

Lets take a look at a very simple example of how matrix multiplication works. Take a look:

$$\begin{bmatrix}
5 & 6
\end{bmatrix} \times
\begin{bmatrix}
1 & 2\\
3 & 4
\end{bmatrix}
= \begin{bmatrix}
(5 \times 1 + 6 \times 3) & (5 \times 2 + 6 \times 4)
\end{bmatrix} = \begin{bmatrix}
(5 + 18) & (10 + 24)
\end{bmatrix} = \begin{bmatrix}
23 & 34
\end{bmatrix}$$

This may look a little complicated at first, but we’re really just taking each number from the row of the vector and multiplying it by the matching number in each column of the matrix. Sometimes it helps to color code it:

 

Notice the red 5 and 6 get multiplied by the green 1 and 3 respectively, then those values are added. That gives us the first value in our resulting vector. Then the red 5 and 6 are also multiplied by the blue 2 and 4 respecitvely, then those values are added. That gives us the second value in our resulting vector.

 

Matrix Times Other Matrix

 

Lets look at two matrices now. It actually works the same way as with a vector, it’s just that our vector only had one row, the [5 6] row. Our matrix has two rows now, so we follow the same pattern  to get our bottom row.

$$\begin{bmatrix}
5 & 6\\
7 & 8
\end{bmatrix} \times
\begin{bmatrix}
1 & 2\\
3 & 4
\end{bmatrix}$$

 

Lets look at the math for this:

$$\begin{bmatrix}
5 & 6\\
7 & 8
\end{bmatrix} \times
\begin{bmatrix}
1 & 2\\
3 & 4
\end{bmatrix} = \begin{bmatrix}
(5 \times 1 + 6 \times 3) & (5 \times 2 + 6 \times 4)\\
(7 \times 1 + 8 \times 3) & (7 \times 2 + 8 \times 4)
\end{bmatrix} = \begin{bmatrix}
23 & 34\\
31 & 46
\end{bmatrix}$$

Notice the top row is exactly the same as our vector example. The bottom row follows the same pattern but uses the bottom row in the first matrix. We can color code this again for clarity:

It’s just rows on the left against columns on the right, multiplying and adding as we saw with the vector.

If you still find this confusing, it may be a good idea to go ahead and watch the Matrix times matrix video from the Further Study section. It may also become more clear after implementing the code in the next section. Keep in mind this is just a set of rules mathematicians came up with as the useful way of multiplying matrices. It’s just a certain set of rules you have to memorize.

Implementing a matrix class in JS

Lets create a 2×2 matrix class in JS and do these same examples in code:

See the Pen
Two by Two Matrix
by Rob Louie (@rlouie)
on CodePen.

Make sure you understand basic matrix multiplication before continuing.

Why does this help us?

We already know how to translate, rotate, and scale our vectors, so why do we need matrices? There are a few reasons, one being performance. Right now we have to take all of our vertices and pass each one to the scale function, the translate function, and the rotate function. In one 3d scene we could easily have 100k vertices, so any extra operation in there would be done an extra 100k times, which we’d like to avoid.

With matrix math we can actually take a scale matrix and multiply it by a rotate matrix (and soon a translate matrix, more later) and get a full transformation matrix. That only has to happen once for all the vertices it applies to. Then this final matrix is multiplied by each vertex and transforms that vertex. This means we can do some of our math only once to build this matrix, then apply it to all vertices.

This also means we can store a certain state in a matrix, which is another benefit of using matrices. I could have one matrix that rotates 90 degrees and scales x3, and another matrix that rotates 180 degrees and scales to 1/2. I could keep both matrices in memory and apply one or the other at a given time.

The Identity Matrix

There’s a special matrix called “the identity matrix”. I’m going to show you what it is and see if you can figure out why.

$$\begin{bmatrix}
1 & 0\\
0 & 1
\end{bmatrix}$$

If you’re not sure, try multiplying it by a vector or matrix and see what the result is.

$$\begin{bmatrix}
5 & 6
\end{bmatrix} \times
\begin{bmatrix}
1 & 0\\
0 & 1
\end{bmatrix} = \begin{bmatrix}
5 \times 1 + 6 \times 0\\
5 \times 0 + 6 \times 1
\end{bmatrix} = \begin{bmatrix}
5\\
6
\end{bmatrix}$$

When you multiply the identity matrix by another matrix or vector, you just end up with that matrix or vector.

With that knowledge, could you figure out how to make a scale matrix? If we have the vector (5, 6) and we want to scale it up 2x to (10, 12), what matrix could do that?

Scale Matrix

Notice in our identity matrix that due to the rules of matrix math, this matrix just returns anything it is multiplied by. This is because anywhere there is a 1 the corresponding matrix or vector component is retained (because anything times one is itself), and anywhere there is a zero the corresponding matrix or vector component is not used (since we take a row times a column and then add them, zero times anything is zero, and a value plus zero is just the value).

So if we wanted to scale something instead, we could simply put the amount we want to scale where the ones are. Here is a matrix that will double the size:

$$\begin{bmatrix}
2 & 0\\
0 & 2
\end{bmatrix}$$

If we do the math here, we see we’ve doubled our vector:

$$\begin{bmatrix}
5 & 6
\end{bmatrix} \times
\begin{bmatrix}
2 & 0\\
0 & 2
\end{bmatrix} = \begin{bmatrix}
5 \times 2 + 6 \times 0\\
5 \times 0 + 6 \times 2
\end{bmatrix} = \begin{bmatrix}
10\\
12
\end{bmatrix}$$

Let’s implement these in code and do the examples there:

See the Pen
Two by Two Matrix Multiplication
by Rob Louie (@rlouie)
on CodePen.

Now you know the basics of matrix multiplication

Hopefully this gave you an introduction into matrix multiplication. If you understand this, you’ll be able to just scale this knowledge up to larger matrices, which we will need in the near future. Before we do that though, we need to explain how rows vs columns work in matrix math. That will be in the next post.

Further Study

Matrix times vector

Matrix times matrix