// Copyright (c) 2024 The Foundry Visionmongers Ltd. All Rights Reserved.
kernel MatricesSpecification : ImageComputationKernel<eComponentWise>
{
Image<eWrite, eAccessPoint> output;
param:
float3x3 mtx3Param;
float4x4 mtx4Param;
void define()
{
/// Matrices can be defined and passed through as params.
defineParam(mtx3Param, "mtx3Param", float3x3({1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f}));
defineParam(mtx4Param, "mtx4Param", float4x4({1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f}));
}
local:
float3x3 mtx3Local;
float4x4 mtx4Local;
void init() {
/// Matrices can be declared as locals and initialised in init().
mtx3Local = {1.0f, 2.0f, 3.0f,
4.0f, 5.0f, 6.0f,
7.0f, 8.0f, 9.0f};
mtx4Local = {1.0f, 2.0f, 3.0f, 4.0f,
5.0f, 6.0f, 7.0f, 8.0f,
9.0f, 10.0f, 11.0f, 12.0f,
13.0f, 14.0f, 15.0f, 16.0f};
mtx3Local.transpose();
mtx4Local = mtx4Local.rotateX(1.0f);
}
void MatrixOperationsExample() {
/// There are two square row-major matrix types available in Blink kernels, 3x3 and 4x4.
// They can be constructed with their elements set either by using an initialising list or regular constructor.
// Matrices can also be left uninitialised and set later.
float3x3 m3x3 = {1.0f, 2.0f, 3.0f,
4.0f, 5.0f, 6.0f,
7.0f, 8.0f, 9.0f};
float4x4 m4x4 (1.0f, 2.0f, 3.0f, 4.0f,
5.0f, 6.0f, 7.0f, 8.0f,
9.0f, 10.0f, 11.0f, 12.0f,
13.0f, 14.0f, 15.0f, 16.0f);
// Values from a matrix can be accessed with the double subscript operator [row][column].
float c01 = m3x3[0][1];
/// Matrices defined in the process method can have their elements updated in a number of useful ways.
// setElements(...): Updates the entire matrix.
m3x3.setElements(2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f);
// setArray(float[N*N]): Alternatively you can use an array to update the matrix values.
// Ensure that the array is the same size as the matrix.
float a[3*3] = {2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f};
m3x3.setArray(a);
// Individual values can be updated separately with the double subscript operator.
m3x3[1][1] = 3.4f;
/// Common matrix patterns have special methods to set them to reduce the amount of manual matrix construction.
// setIdentity(): Creates the NxN identity matrix.
m3x3.setIdentity();
// setTranslate(floatN): Creates an identity matrix with a translation vector on the rightmost column.
m3x3.setTranslate(float3(1.0f, 1.0f, 1.0f));
// setScale(floatN): Creates a diagonal matrix with the values of the vector.
m3x3.setScale(float3(2.0f, 2.0f, 2.0f));
// setRotate(angle): Creates a 3x3 rotation matrix for the input angle in radians for the 2D coordinate system (3x3 matrices only).
m3x3.setRotate(PI/4);
// setRotateX(angle): Creates a 4x4 rotation matrix about the X axis for the input angle in radians for the 3D coordinate system (4x4 matrices only).
m4x4.setRotateX(PI/4);
// setRotateY(angle): Creates a 4x4 rotation matrix about the Y axis for the input angle in radians for the 3D coordinate system (4x4 matrices only).
m4x4.setRotateY(PI/4);
// setRotateZ(angle): Creates a 4x4 rotation matrix about the Z axis for the input angle in radians for the 3D coordinate system (4x4 matrices only).
m4x4.setRotateZ(PI/4);
/// There are a number of methods the matrix object provides.
/// Each of the following methods operates on the matrix in place as well as returning a reference for assigning other matrices.
/// E.g. mat.transpose() will transpose the m3x3 matrix.0f, mat2 = mat1.transpose() will transpose the mat1 matrix and assign the result to mat2.
// translate(floatN): Creates a translation matrix T and left multiplies the matrix in place.
m3x3.translate(float3(1.0f, 1.0f, 1.0f));
// scale(floatN): Creates a scale matrix S and left multiplies the matrix in place.
m3x3.scale(float3(2.0f, 3.0f, 4.0f));
// rotate(angle): Creates a rotation matrix R and left multiplies the matrix in place (3x3 matrices only).
m3x3.rotate(PI/4);
// rotateX(angle): Creates a rotation matrix about the X axis and left multiplies the matrix in place (4x4 matrices only).
m4x4.rotateX(PI/4);
// rotateY(angle): Creates a rotation matrix about the Y axis and left multiplies the matrix in place (4x4 matrices only).
m4x4.rotateY(PI/4);
// rotateZ(angle): Creates a rotation matrix about the Z axis left multiplies the matrix in place (4x4 matrices only).
m4x4.rotateZ(PI/4);
// transpose(): Computes the transpose of the matrix.
m3x3.transpose();
// invert(): Computes the inverse of the matrix. Ensure that it can be inverted before running this.
m3x3.invert();
/// Matrix operators.
float3x3 A = {1.0f, 5.0f, 1.0f, 1.0f, 1.0f, 3.0f, 1.0f, 1.0f, 1.0f};
float3x3 B = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f};
float3x3 C;
// Matrix addition.
C = A + B;
// Matrix subtraction.
C = A - B;
// Matrix * Matrix multiplication.
C = A * B;
// Matrix * Vector multiplication.
float3 AxV = A * float3(2.0f, 2.0f, 2.0f);
// Write out result of matrix operation to image.
output() = A[2][1];
}
void process() {
MatrixOperationsExample();
}
};