旋转、平移和默认相机位置

Rotation, Translation and Default Camera Location

我只是在研究 MTKView 中的模板设置;而且,我一直在努力理解以下内容:

  1. 相机的默认位置。

  2. 使用MDLMeshMTKMesh创建图元时的默认位置。

  3. 为什么旋转也涉及平移。

相关代码:

matrix_float4x4 base_model = matrix_multiply(matrix_from_translation(0.0f, 0.0f, 5.0f), matrix_from_rotation(_rotation, 0.0f, 1.0f, 0.0f));
matrix_float4x4 base_mv = matrix_multiply(_viewMatrix, base_model);
matrix_float4x4 modelViewMatrix = matrix_multiply(base_mv, matrix_from_rotation(_rotation, 0.0f, 1.0f, 0.0f));

以上代码来自模板的_update方法;显然,它试图旋转模型而不是相机。但令我困惑的是,它还需要翻译。我读过诸如 "because it always rotates at (0, 0, 0)" 之类的说法。但是为什么(0, 0, 0),如果对象放在别的地方呢?此外,在我看来,相机正在查看正 z 轴(问题 1)而不是通常的负 z 轴,因为如果我更改:

matrix_float4x4 base_model = matrix_multiply(matrix_from_translation(0.0f, 0.0f, 5.0f), matrix_from_rotation(_rotation, 0.0f, 1.0f, 0.0f));

至:

matrix_float4x4 base_model = matrix_multiply(matrix_from_translation(0.0f, 0.0f, -5.0f), matrix_from_rotation(_rotation, 0.0f, 1.0f, 0.0f));

屏幕上不会显示任何内容,因为对象似乎在相机后面,这意味着相机正在注视正 z 轴。

如果我设置 matrix_from_translation(0.0f, 0.0f, 0.0f)(全为零),对象只是像我预期的那样在 y 轴上旋转(问题 3)。

我试图找出 MDLMeshMTKMesh 默认放置的位置(问题 2),但我找不到 属性 记录它的位置。以下也是通过模板创建图元的方式:

MDLMesh *mdl = [MDLMesh newBoxWithDimensions:(vector_float3){2,2,2} segments:(vector_uint3){1,1,1}
                geometryType:MDLGeometryTypeTriangles inwardNormals:NO
                allocator:[[MTKMeshBufferAllocator alloc] initWithDevice: _device]];

_boxMesh = [[MTKMesh alloc] initWithMesh:mdl device:_device error:nil];

在不知道上述方法生成的位置的情况下,这妨碍了我理解旋转和平移的工作原理以及相机在 Metal 中的默认位置。

谢谢。

我认为矩阵在代码中的编写顺序有点混淆了意图,所以我将实际发生的事情归结为以下伪代码,以便于解释。

我已将最后一个矩阵替换为模板中的矩阵,因为您的修改仅具有使绕 Y 轴旋转加倍的效果。

modelViewMatrix = identity *
                  translate(0, 0, 5) *
                  rotate(angle, axis(0, 1, 0)) *
                  rotate(angle, axis(1, 1, 1))

由于矩阵在着色器中向量的左侧相乘,我们将从右到左读取矩阵以确定它们的累积效果。

首先,我们围绕通过原点对角线的轴 (1, 1, 1) 旋转立方体。然后,我们绕立方体绕 Y 轴旋转。这些旋转结合形成一种 "tumble" 动画。然后,我们将立方体沿 +Z 轴平移 5 个单位(如您所见,它进入屏幕,因为我们将我们的世界视为左撇子)。最后,我们应用我们的相机变换,它被硬编码为单位矩阵。我们可以沿 +Z 使用额外的正平移作为相机矩阵,将立方体从相机移得更远,或者使用负值将立方体移近。

回答您的问题:

  1. 相机没有默认位置,除了原点 (0, 0, 0) 如果您想这样想的话。您 "position" 通过将顶点位置乘以表示相机在世界中的放置方式的变换的逆,您可以在世界中设置相机。

  2. 模型 I/O 构建围绕原点 "centered" 的网格,在某种程度上这对生成的形状有意义。圆柱体、椭圆体和长方体实际上以原点为中心,而圆锥体的顶点在原点,轴沿 -Y 延伸。

  3. 旋转并没有真正涉及翻译,而是 与翻译相结合。平移的原因是我们需要将立方体放置在远离相机的位置;否则我们在绘图时会在里面。

关于操作顺序的最后一点说明:如果我们在 旋转之前应用平移 ,它会导致框 "orbit" 围绕相机,因为当你请注意,旋转始终相对于当前参考系的原点。