问题描述
我得到了一个旧的 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];
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;