# Matrices

by Lea Rosema

Matrices are rectangular arrays of numbers. In computer graphics, matrices are helpful for performing transformations in 2D or 3D space, like translation, rotation and scaling.

These transformations are done via matrix multiplication. The GLSL shader language has matrix multiplication built-in, in JavaScript you have to use an additional matrix library (or implement that yourself).

### Defining Matrices in GLSL

anchor

One mindtwisting detail when working with matrices in GLSL is, you don't write matrices in GLSL as you would write them down on paper, but in a transposed form:

``````mat3 identity() {
return mat3(
vec3(  1.,  0., 0.), // column 1
vec3(  0.,  1., 0.), // column 2
vec3(  0,   0 , 1.)  // column 3
);
}``````

Above, you can see an example of the identity matrix, this behaves like the number `1`, when multiplying a matrix with the identity matrix, you will get the same matrix as the result (`A*I = A`).

### 2D transformation matrices

anchor

#### Rotation matrix

anchor
``````mat3 rotate2D(float a) {
float C = cos(a);
float S = sin(a);
return mat3(
vec3( C, S, 0.),
vec3(-S, C, 0.),
vec3( 0, 0, 1.)
);
}``````

#### Translation matrix

anchor
``````mat3 translate2D(vec2 t) {
return mat3(
vec3(  1.,  0., 0.),
vec3(  0.,  1., 0.),
vec3( t.x, t.y, 1.)
);
}``````

#### Scale matrix

anchor
``````mat3 scale2D(vec2 s) {
return mat3(
vec3( s.x,  0., 0.),
vec3(  0., s.y, 0.),
vec3(  0.,  0., 1.)
);
}``````

#### Usage

anchor
``````const float PI = 3.141592654;
const float DEG = PI / 180.;

void main() {
mat3 mRotate = rotate2D(rotate * DEG);
mat3 mTranslate = translate2D(vec2(translateX, translateY));
mat3 mScale = scale2D(vec2(scaleX, scaleY));

// try changing the order of the multiplications :)
mat3 mTransform = mTranslate * mRotate * mScale;
vec3 pos = mTransform * vec3(position.xy, 1.);
vPos = pos.xy;
gl_Position = vec4(pos.xy,0.,1.);
}``````

Try on CodePen

### 3D transformation matrices

anchor

#### 3D Rotation matrices

anchor

In 3D space, you can rotate around the X, Y and Z axis:

``````mat4 rotX(float angle) {
float S = sin(angle);
float C = cos(angle);
return mat4(
vec4(1.0, 0, 0, 0),
vec4(0  , C, S, 0),
vec4(0  ,-S, C, 0),
vec4(0  , 0, 0, 1.0)
);
}

mat4 rotY(float angle) {
float S = sin(angle);
float C = cos(angle);
return mat4(
vec4(C, 0  ,-S, 0),
vec4(0, 1.0, 0, 0),
vec4(S, 0  , C, 0),
vec4(0, 0  , 0, 1.0)
);
}

mat4 rotZ(float angle) {
float S = sin(angle);
float C = cos(angle);
return mat4(
vec4( C, S, 0  , 0),
vec4(-S, C, 0  , 0),
vec4( 0, 0, 1.0, 0),
vec4( 0, 0, 0  , 1.0)
);
}``````

#### 3D Scale matrix

anchor
``````mat4 scale(vec3 s) {
return mat4(
vec4(s.x, 0.0, 0.0, 0.0),
vec4(0.0, s.y, 0.0, 0.0),
vec4(0.0, 0.0, s.z, 0.0),
vec4(0.0, 0.0, 0.0, 1.0)
);
}``````

#### 3D Translation matrix

anchor
``````mat4 translate(vec3 p) {
return mat4(
vec4(1.0, 0.0, 0.0, 0.0),
vec4(0.0, 1.0, 0.0, 0.0),
vec4(0.0, 0.0, 1.0, 0.0),
vec4(p.x, p.y, p.z, 1.0)
);
}``````

anchor

Try on CodePen