XNA/OpenGL 是否使用左手矩阵?

Does XNA/OpenGL use left handed matrices?

据我了解,OpenGL和XNA都默认使用右手坐标系。

但是看起来这两个库生成的旋转矩阵都是左手的。

我认为这是因为正 Z 轴旋转会产生这样计算的矩阵(此表示中的行主要):

cos  |  sin  |  0
-sin |  cos  |  0
  0  |   0   |  1

根据我找到的资料,这是一个左手 Z 旋转矩阵 (http://www.cprogramming.com/tutorial/3d/rotationMatrices.html)

我的问题是:

  1. 我说的对吗?矩阵是左手的但坐标系是右手的吗?
  2. XNA/OpenGL的所有矩阵方法都是这样吗?
  3. 如果我是对的,这有什么关系?为什么不把所有东西都变成右手?

在像 OpenGL 这样的图形 API 中,没有一个单一的坐标系。在通过管道进行时,可以多次变换顶点。由于线性变换实际上与坐标系的变化是一回事,因此您可以想象每个变换都引入了一个新的坐标系。

基于此,应用程序可以在很大程度上决定他们想要在哪个坐标系中工作。对于当前版本的 OpenGL 中使用的可编程管道尤其如此,但在某种程度上也适用于传统的固定管道。

让我详细说明这方面的一些方面,这应该涵盖您对 OpenGL 的问题。

归一化设备坐标

标准化设备坐标 (NDC) 是顶点处理完成后顶点所在的坐标系。您可以将其视为 OpenGL 的 "native" 3D 坐标系。它的所有 3 个坐标的范围都是 [-1.0, 1.0],并且是 左手.

固定管道

在遗留固定管线中,顶点最初在对象坐标中指定(参见http://www.glprogramming.com/red/chapter03.html)。模型视图矩阵将它们转换为 眼睛坐标 ,投影矩阵将其转换为 剪辑坐标 。透视分割后成为NDC

对象坐标最常用的是右手坐标系。使用保留惯用手的模型视图矩阵,这导致眼睛坐标仍然是右手的。投影矩阵翻转z轴的方向,导致左手剪辑坐标和NDC。

如果你选择这样,你可以很容易地使用左手对象坐标,并使用翻转手性的模型视图矩阵,这样你最终又会得到右手眼坐标。

可编程管道

通过可编程管线,您可以完全自由地在顶点着色器中使用您想要的任何坐标系。假设您的原始顶点是在球坐标中指定的,那根本没问题。您只需要在着色器代码中相应地处理它们。顶点着色器需要产生剪辑坐标(如前所述是左手坐标)作为输出,但在此之前的一切都是完全开放的。

旋转

当前版本的 OpenGL 没有任何旋转概念,也没有创建旋转矩阵的内置功能。

对于与遗留固定管道一起使用的 glRotatef() 函数,矩阵不是您在问题中所拥有的。围绕 z 轴的旋转由此矩阵定义:

[ cos(a)  -sin(a)  0  0 ]
[ sin(a)  cos(a)   0  0 ]
[ 0       0        1  0 ]
[ 0       0        0  1 ]

您可以在 http://www.glprogramming.com/red/appendixf.html 的一半处找到这个矩阵。

所以这是一个右手坐标系的旋转矩阵。这与我在上面 "Fixed Pipeline".

下描述的常见用法相符

编号问题的答案

基于此 material,以下是您最后编号问题的答案:

  1. 没有。旋转矩阵(至少由已弃用的固定函数 API 调用构造)被构建为使用右手坐标系。而 "native" 坐标系 (NDC) 是左手坐标系。
  2. 对于模型变换,它只对旋转产生影响,旋转假定它们在右手坐标系中运行。投影矩阵从右手翻转到左手。
  3. 左撇子与右撇子很重要,例如,如果您正在查看三角形的缠绕顺序,或者如果您正在使用叉积计算法线。为什么 NDC 是左撇子……我不知道。它一开始就是这样定义的(我怀疑它甚至可能从 GL 转移到 OpenGL)。一旦以一种方式定义,您就不能再更改它而不会破坏兼容性。