Multiplying Matrices
The benefit of matrices is realized when we concatenate or multiply a long sequence of them into a single matrix, but how exactly do we multiply two rectangular grids of numbers?
In GLSL, we can just use the native matrix type mat4
and the *
operator:
mat4 chain = scale * rotate * translate;
mat4 chain = scale * rotate * translate;
In JavaScript, we don't have a native matrix type, but we can write our own Matrix4
class and define a multiplyMatrix
method. We'd then multiply the matrices together with code like this:
const chain = scale.
multiplyMatrix(rotate).
multiplyMatrix(translate);
const chain = scale. multiplyMatrix(rotate). multiplyMatrix(translate);
How do we implement the multiplyMatrix
method?
We've seen how matrix-vector multiplication works. Each row of the matrix gets dotted with the vector to produce the components of the product vector. Matrix-matrix multiplication is an extension of this idea.
The product of multiplying two 4×4 matrices is itself a 4×4 matrix. Each component of this new matrix is computed by dotting a row from the left operand matrix and a column from the right operand matrix. Get a visceral feel for which vectors are involved by hovering your mouse over or tapping a component in one of the right-hand side matrices in this multiplication:
When you hover your mouse over the component in the first row and first column, which vector from the left operand is dotted with which vector from the second operand? What changes when you move to the second column? The third column? The fourth column? The second row?
Based on this exploration, we compose this pseuocode formula for calculating the component at row r
and column c
of the product matrix:
product[r, c] = dot(row r of left, column c of right)
product[r, c] = dot(row r of left, column c of right)
Computing all 16 components is tedious to do by hand. We will let the computer do the work. To eliminate the slight overhead of loops and function calls, graphics developers will often write out the sixteen dot products. These four equations, for example, compute the components in the top row of the product matrix:
This notation follows the convention of listing first the row and then the column in the subscripts. For example, \(p_{02}\) refers to the component at row 0 and column 2.
The remaining rows are computed similarly.
Understanding how transformation matrices combine into a single matrix takes practice. To get some practice, check out Transformula, a sandbox for sequencing tranformations and examining their matrix representations. The tool is a work-in-progress.