See:

## GLSL

GLSL is OpenGL's shader language. webGPU is coming up with its own shader language, but as of this writing (Oct 13, 2020), the shader language it uses is SPIR-V, which can be cross-compiled from GLSL pretty well.

### Matrices: Row-Order vs Column-Order

OpenGL and, by extension, its shading language GLSL, use a column-order mapping for its matrices, e.g., mat4.

By contrast, my game engine Grimoire utilizes row-order mapping for its matrix, Matrix44.

A matrix in column order:

1. has its translation components in the 4th column.
2. has its rotational components along the x-, y-, and z-axes in the first, second, and third columns respectively.

A matrix in row order:

1. has its translation components in the 4th row.
2. has its rotational components along the x-, y-, and z-axes in the first, second, and third rows respectively.

Luckily, when Grimoire lays out its Matrix44 sequentially in memory as a 1-dimensional array, when GLSL reads and instantiates the memory data into its mat4 object, it correctly places the components in its necessary locations.

1D Array Index0123456789101112131415
Matrix44m00m01m02m03m10m11m12m13m20m21m22m23m30m31m32m33
mat4m00m10m20m30m01m11m21m31m02m12m22m32m03m13m23m33

From the table above, you can see that the translation components of a Matrix44, located at m30, m31, and m32, will be placed in the 1D array at indices 12, 13, and 14, respectively.

When GLSL reads the 1D array, it'll take the data at indices 12, 13, and 14, and place them correctly in the 4th column, at m03, m13, and m23, respectively.

### Matrices: Multiplication

In GLSL, multiplication between two mat4s work as you would expect. The left-hand mat4's rows are cross-multiplied against the right-hand mat4's columns to generate another mat4.

Also, as you would expect, matrix multiplication is NOT commutative. Ma * Mb != Mb * Ma.