Understanding GLSL matrixCompMult

The matrixCompMult function in the OpenGL Shading Language (GLSL) executes component-wise multiplication between two matrices of identical dimensions, rather than standard algebraic matrix multiplication. This guide covers how matrixCompMult calculates its output, how it differs from the standard multiplication operator (*), and when to use it in shader programming.

What matrixCompMult Does

In GLSL, matrixCompMult performs what is mathematically known as the Hadamard product or element-wise product. It takes two matrices of the same size and multiplies their corresponding components individually.

If matrix \(A\) and matrix \(B\) are passed into matrixCompMult(A, B), each entry in the resulting matrix \(C\) is calculated as:

\[C[i][j] = A[i][j] \times B[i][j]\]

Where \(i\) represents the column index and \(j\) represents the row index.

Difference Between matrixCompMult and *

It is common to confuse matrixCompMult with the standard GLSL multiplication operator (*):

  • The * Operator (Linear Algebraic Multiplication): When using A * B between two matrices, GLSL performs standard linear algebra matrix multiplication (computing the dot product of rows from \(A\) and columns from \(B\)). The number of columns in \(A\) must equal the number of rows in \(B\).
  • The matrixCompMult Function (Component-wise): When using matrixCompMult(A, B), no row-by-column dot products are calculated. Instead, each individual element is multiplied directly by its counterpart.

Syntax and Type Requirements

The function signature supports all standard floating-point matrix types, including non-square matrices:

mat2 matrixCompMult(mat2 x, mat2 y);
mat3 matrixCompMult(mat3 x, mat3 y);
mat4 matrixCompMult(mat4 x, mat4 y);

mat2x3 matrixCompMult(mat2x3 x, mat2x3 y);
mat3x2 matrixCompMult(mat3x2 x, mat3x2 y);
// ...and other variations up to mat4x4

Both input matrices must have identical dimensions and component types. The returned matrix has the same dimension as the inputs.

Practical Example

Consider two \(2 \times 2\) matrices:

mat2 A = mat2(
    2.0, 3.0,  // Column 0
    4.0, 5.0   // Column 1
);

mat2 B = mat2(
    1.0, 2.0,  // Column 0
    0.5, 3.0   // Column 1
);

mat2 result = matrixCompMult(A, B);

The operation multiplies matching indices:

  • result[0][0] = 2.0 * 1.0 = 2.0
  • result[0][1] = 3.0 * 2.0 = 6.0
  • result[1][0] = 4.0 * 0.5 = 2.0
  • result[1][1] = 5.0 * 3.0 = 15.0

The resulting matrix is:

mat2(
    2.0, 6.0,  // Column 0
    2.0, 15.0  // Column 1
);

Common Use Cases

  • Weighting and Masking: Applying per-element scale factors or masks to transformations or matrix-packed parameters.
  • Component-wise Blending: Modulating matrix-based data arrays directly inside vertex or fragment shaders without unpacking them into individual vectors.
  • Custom Numerical Computations: Implementing scientific or custom physics models that require element-by-element matrix math directly on the GPU.