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)
我的问题是:
- 我说的对吗?矩阵是左手的但坐标系是右手的吗?
- XNA/OpenGL的所有矩阵方法都是这样吗?
- 如果我是对的,这有什么关系?为什么不把所有东西都变成右手?
在像 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,以下是您最后编号问题的答案:
- 没有。旋转矩阵(至少由已弃用的固定函数 API 调用构造)被构建为使用右手坐标系。而 "native" 坐标系 (NDC) 是左手坐标系。
- 对于模型变换,它只对旋转产生影响,旋转假定它们在右手坐标系中运行。投影矩阵从右手翻转到左手。
- 左撇子与右撇子很重要,例如,如果您正在查看三角形的缠绕顺序,或者如果您正在使用叉积计算法线。为什么 NDC 是左撇子……我不知道。它一开始就是这样定义的(我怀疑它甚至可能从 GL 转移到 OpenGL)。一旦以一种方式定义,您就不能再更改它而不会破坏兼容性。
据我了解,OpenGL和XNA都默认使用右手坐标系。
但是看起来这两个库生成的旋转矩阵都是左手的。
我认为这是因为正 Z 轴旋转会产生这样计算的矩阵(此表示中的行主要):
cos | sin | 0
-sin | cos | 0
0 | 0 | 1
根据我找到的资料,这是一个左手 Z 旋转矩阵 (http://www.cprogramming.com/tutorial/3d/rotationMatrices.html)
我的问题是:
- 我说的对吗?矩阵是左手的但坐标系是右手的吗?
- XNA/OpenGL的所有矩阵方法都是这样吗?
- 如果我是对的,这有什么关系?为什么不把所有东西都变成右手?
在像 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,以下是您最后编号问题的答案:
- 没有。旋转矩阵(至少由已弃用的固定函数 API 调用构造)被构建为使用右手坐标系。而 "native" 坐标系 (NDC) 是左手坐标系。
- 对于模型变换,它只对旋转产生影响,旋转假定它们在右手坐标系中运行。投影矩阵从右手翻转到左手。
- 左撇子与右撇子很重要,例如,如果您正在查看三角形的缠绕顺序,或者如果您正在使用叉积计算法线。为什么 NDC 是左撇子……我不知道。它一开始就是这样定义的(我怀疑它甚至可能从 GL 转移到 OpenGL)。一旦以一种方式定义,您就不能再更改它而不会破坏兼容性。