Matrices Overview
WGSL supports matrices between \(2 \times 2\) and \(4 \times 4\) f32 elements.
Matrices are declared with the form matCxR<f32>, where C is the number of columns in the matrix, and R is the number of rows in the matrix.
Example Matrix Declarations
| Type | Description |
|---|---|
mat2x3<f32> |
A matrix with two columns and three rows of f32. |
mat4x2<f32> |
A matrix with four columns and two rows of f32. |
matCxR<T> can be thought of as C column vectors of vecR<T>.
WGSL also predeclares the alias matCxRf as an alias for matCxR<f32>.
What is "Column-Major"?
In WGSL, matrices are column-major. This is a critical concept to understand when working with matrix elements and indexing:
- Column Vector Basis: A matrix is treated as a collection of column vectors side-by-side, rather than row vectors. For example, a
mat3x3fconsists of 3 columns, where each column is avec3f. - Left-to-Right Construction: When you initialize a matrix with values (or elements/vectors), you specify them column by column (left-to-right), rather than row by row.
- First Index is Column: If you index a matrix using
my_matrix[i], it extracts the \(i\)-th column vector (0-based), not a row. - Double Indexing is
[column][row]: To access a specific scalar element, usemy_matrix[col][row]. For instance,my_matrix[1][2]accesses the element at Column 1, Row 2. - Memory Layout: In memory, the elements of the first column are stored sequentially, followed by the elements of the second column, and so on.
Next Steps
Matrix operations and usage:
- Matrix Constructors: Initialization forms including zero-value, column-wise, and scalar-wise constructors.
- Matrix Multiplication: Linear algebra operations, including scalar, vector, and matrix multiplications.
/*
* Copyright ©2026 Michael R. Bernstein. Licensed under Apache 2.0.
* See root README.md for global project-wide upstream attributions.
*/
const my_matrix = mat3x3f(
vec3f(1.0, 2.0, 3.0), // Column 0
vec3f(4.0, 5.0, 6.0), // Column 1
vec3f(7.0, 8.0, 9.0) // Column 2
);
fn get_column_1() -> vec3f {
return my_matrix[1]; // Resolves to Column 1: vec3f(4.0, 5.0, 6.0)
}
fn get_element_1_2() -> f32 {
return my_matrix[1][2]; // Column 1, Row 2 (0-based) -> 6.0
}
const m2x2 = mat2x2f(1.0, 2.0, 3.0, 4.0);