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

问题描述

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

我正在查看有关使用矩阵的 Apple 文档,但没有看到他们在示例中使用的下标类型。文档表明它是 [column],[row]。 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];

enter image description here

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

解决方法

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

矩阵是按行和列排列的二维值数组。 [...] 它使用列主要命名约定;例如,simd_double4x2 是一个包含四列两行的矩阵。

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

矩阵组件按列主序构造和使用

列主序是什么意思?

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

至于下标怎么写,还是比较简单的。在 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;