Construct Column-Major Matrices in GLSL

This article explains how to construct matrices from vector components in the OpenGL Shading Language (GLSL). It covers GLSL’s native column-major memory layout, provides standard constructor syntax for mat2, mat3, and mat4 types using input vectors, and demonstrates how to properly access and manipulate the resulting matrix columns.

Understanding GLSL Column-Major Ordering

GLSL matrices are natively defined as arrays of column vectors. When you provide multiple vectors to a matrix constructor, GLSL interprets each argument sequentially as a distinct column from left to right, rather than as a row.

This means that accessing a matrix with standard bracket notation follows the matrix[column][row] convention. For instance, myMatrix[0] accesses the entire first column vector, and myMatrix[0][1] accesses the second element of that first column.

Constructing Matrices from Vectors

To build a matrix, you pass vectors that match the row dimension of the matrix. The number of vector arguments must match the column dimension of the target matrix.

Constructing a mat2

A mat2 consists of two columns with two rows each. It is initialized using two vec2 instances:

vec2 col0 = vec2(1.0, 2.0);
vec2 col1 = vec2(3.0, 4.0);

// Resulting matrix:
// [ 1.0  3.0 ]
// [ 2.0  4.0 ]
mat2 m = mat2(col0, col1);

Constructing a mat3

A mat3 represents a 3x3 matrix. Supplying three vec3 vectors assigns each vector to a respective column:

vec3 col0 = vec3(1.0, 0.0, 0.0);
vec3 col1 = vec3(0.0, 1.0, 0.0);
vec3 col2 = vec3(0.0, 0.0, 1.0);

// Resulting matrix:
// [ 1.0  0.0  0.0 ]
// [ 0.0  1.0  0.0 ]
// [ 0.0  0.0  1.0 ]
mat3 m = mat3(col0, col1, col2);

Constructing a mat4

Similarly, a 4x4 matrix (mat4) takes four vec4 vectors representing its four columns:

vec4 col0 = vec4(1.0, 0.0, 0.0, 0.0);
vec4 col1 = vec4(0.0, 1.0, 0.0, 0.0);
vec4 col2 = vec4(0.0, 0.0, 1.0, 0.0);
vec4 col3 = vec4(10.0, 20.0, 30.0, 1.0); // Translation column

mat4 transform = mat4(col0, col1, col2, col3);

Non-Square Matrix Constructors

GLSL also supports non-square matrices formatted as matNxM, where N is the number of columns and M is the number of rows.

To create a mat2x3 (2 columns, 3 rows), provide two vec3 vectors:

vec3 col0 = vec3(1.0, 2.0, 3.0);
vec3 col1 = vec3(4.0, 5.0, 6.0);

// Two columns of three elements
mat2x3 m = mat2x3(col0, col1);

Handling Row-Major Source Data

If your source data is organized in row-major order (where vectors represent rows instead of columns), construct the matrix using the standard column constructor and then invert the orientation using the built-in transpose function:

vec3 row0 = vec3(1.0, 2.0, 3.0);
vec3 row1 = vec3(4.0, 5.0, 6.0);
vec3 row2 = vec3(7.0, 8.0, 9.0);

// Construct as columns, then transpose to treat vectors as rows
mat3 m = transpose(mat3(row0, row1, row2));