iOS Metal 如何使用下标访问 3x3 矩阵的元素?

iOS Metal how to access elements of a 3x3 matrix using subscripts?

我得到了一个旧的 Apple 示例,我正在使用现代语法重写它(示例是使用带有 Objective C++ 的 Metal)。它做了很多缩写,我正在尝试解码他们用矩阵所做的事情,这相当困难。部分问题是我不知道他们是否正在使用 [row][column] 读取矩阵,如 x,y 或 [column],[row].

我正在查看有关使用矩阵的 Apple 文档,但没有看到他们在示例中使用的下标类型。文档表明它是[列],[行]。 https://developer.apple.com/documentation/accelerate/working_with_matrices

uint2 position = uint2(0,0);
matrix_float3x3 cameraIntrinsicsInversed = ...;
const float depth = 10.0f;

const float xrw = (position.x - cameraIntrinsics[2][0]) * depth / cameraIntrinsics[0][0];
const float yrw = (position.y - cameraIntrinsics[2][1]) * depth / cameraIntrinsics[1][1];

pointCloud[index].position = simd_float3(xrw, yrw, depth);

// later, in the vertex shader:
const auto position = pointCloud[index].position;
float4 projectedPosition = viewProjectionMatrix * float4(position, 1.0);

如果我想要特定的行和列元素,如何使用下标正确访问 3x3 矩阵的元素?

我试过了:

// Cannot initialize a variable of type 'const float' with an lvalue of type 'const vec<float, 3>' (vector of 3 'float' values)
const float tx = cameraIntrinsics[2, 0]; 
const float ty = cameraIntrinsics[2, 1];

//again, I'm not sure if I'm getting a column or row here
const float tx = cameraIntrinsics.columns[2][0]; 
const float ty = cameraIntrinsics.columns[2][1];

var matrix = matrix_identity_float3x3
matrix[2, 0] = tx // this is swift syntax

Metal 和 simd 中的矩阵对矩阵使用列主排序。例如,参见 Working with Matrices:

A matrix is a 2D array of values arranged in rows and columns. [...] It uses a column major naming convention; for example, a simd_double4x2 is a matrix containing four columns and two rows.

此外,如果您查看 Metal Languages Specification,第 2.3.2 节,它说:

Matrix components are constructed and consumed in column-major order

列优先顺序是什么意思?

基本上,这意味着方括号中的第一个下标将是列的索引,第二个下标是行的索引。此外,column major 意味着矩阵在内存中逐列排列。如果您混合搭配不同的数学库,您可能会因此而感到困惑,因为某些使用行优先顺序。

至于下标怎么写,还算简单。在 Metal Language Specification 部分 2.3.1 中有一个代码示例

float4x4 m;
// This sets the 2nd column to all 2.0. 
m[1] = float4(2.0f);
// This sets the 1st element of the 1st column to 1.0. 
m[0][0] = 1.0f;
// This sets the 4th element of the 3rd column to 3.0.
m[2][3] = 3.0f;