GLSL Transpose on Non-Square Matrices

The transpose built-in function in the OpenGL Shading Language (GLSL) swaps the row and column indices of any valid matrix type. When applied to non-square matrices, it inverts the dimensional shape of the matrix—converting a matrix with \(C\) columns and \(R\) rows into one with \(R\) columns and \(C\) rows—while remapping the individual components across the main diagonal.

Dimensional Transformation

GLSL specifies matrix types in column-major order using the notation matCxR, where C represents the number of columns and R represents the number of rows. When you pass a non-square matrix to transpose(), the return type is automatically converted to match the swapped dimensions:

  • A mat2x3 (2 columns, 3 rows) becomes a mat3x2 (3 columns, 2 rows).
  • A mat2x4 (2 columns, 4 rows) becomes a mat4x2 (4 columns, 2 rows).
  • A mat3x2 (3 columns, 2 rows) becomes a mat2x3 (2 columns, 3 rows).
  • A mat3x4 (3 columns, 4 rows) becomes a mat4x3 (4 columns, 3 rows).
  • A mat4x2 (4 columns, 2 rows) becomes a mat2x4 (2 columns, 4 rows).
  • A mat4x3 (4 columns, 3 rows) becomes a mat3x4 (3 columns, 4 rows).

Component Mapping

The mathematical operation behind transpose maps every element at column \(j\) and row \(i\) in the source matrix to column \(i\) and row \(j\) in the target matrix:

\[\text{Result}[i][j] = \text{Source}[j][i]\]

Because GLSL addresses matrices using matrix[column][row], the indices simply swap order. The first column of the original matrix becomes the first row of the transposed matrix, the second column becomes the second row, and so forth.

Code Example

// Define a 2-column, 3-row matrix
mat2x3 originalMat = mat2x3(
    1.0, 2.0, 3.0,  // Column 0
    4.0, 5.0, 6.0   // Column 1
);

// Transpose the matrix
mat3x2 transposedMat = transpose(originalMat);

// transposedMat is now a 3-column, 2-row matrix:
// Column 0: (1.0, 4.0)
// Column 1: (2.0, 5.0)
// Column 2: (3.0, 6.0)

Purpose and Common Uses

Non-square matrices are frequently used in graphics programming to reduce register usage and bandwidth when full \(4\times4\) transforms are unnecessary, such as in affine transformations (\(4\times3\) or \(3\times4\) matrices) or 2D projection mathematics. Using transpose on non-square matrices allows shaders to:

  1. Align Storage Formats: Convert data stored in row-major uniform buffers directly into GLSL's native column-major processing format.
  2. Switch Vector Multiplication Order: Enable vector-matrix multiplication equivalencies, converting \((M \cdot v)\) operations into \((v \cdot M^T)\) formulations.
  3. Restructure Projections: Reorient packed transformation matrices for skinning, instancing, or custom geometric projections without manual component shuffling.