OpenGL坐标系是左撇子还是右撇子?

341*_*008 82 opengl coordinates

我试图了解OpenGL坐标系.然而,一些教程说默认坐标系是左撇子(见http://www.c-sharpcorner.com/UploadFile/jeradus/OpenGLBasics11172005014307AM/OpenGLBasics.aspx),其他人说这是右手(参见http:// www .falloutsoftware.com/tutorials/gl/gl0.htm).哪个是对的?我知道我们可以通过镜像将一个转换为另一个,但我想知道默认坐标.

bob*_*obo 126

这里有一些混乱.

在此输入图像描述

OpenGL是对象空间和世界空间的右手.

但在窗口空间(又名屏幕空间),我们突然左撇子.

这是怎么发生的

我们从右手到左手的方式是在一个负z缩放进入glOrthoglFrustum投影矩阵.将z缩放-1(同时保留x和y)具有改变坐标系的旋向性的效果.

对于glFrustum,

在此输入图像描述 在此输入图像描述

近的应该是积极的, > .说 = 1000并且接近 = 1.然后C = - (1001)/(999)= -1.002.

有关详细信息和图表,请参见此处.

正交的角度来看,glOrtho生成如下矩阵:

在此输入图像描述

这里,,,顶部只是左垂直,右垂直,底水平,顶水平剪裁平面(resp)的坐标.

的飞机,然而,在不同的规定.的邻近参数定义为

  • 近:距离较近的深度剪裁平面的距离.如果平面要在观察者后面,则该距离为负.

远:

  • zFar 到更远深度剪裁平面的距离.如果平面要在观察者后面,则该距离为负.

这里我们有一个典型的规范视图卷

典范

因为z乘数是(-2 /(远近)),所以减号有效地将z缩放-1.这意味着在观看转换过程中"z"被左手转动,大多数人都不知道,因为它们只是在OpenGL中作为"右手"坐标系统工作.

所以,如果你打电话

glOrthof(-1, 1, -1, 1, 10, -10) ; // near=10, FAR=-10,
Run Code Online (Sandbox Code Playgroud)

然后NEAR PLANE 比你前面10个单位.你在哪?为什么,在原点,右边的x轴,头顶的y轴,以及指向负z轴的鼻子(这是默认的"默认情况下,相机位于原点,指向负z轴,并具有向上的(0,1,0).").所以近平面在z = -10.远飞机比你落后10个单位,z = + 10.

  • _我们突然变成了左撇子_从剪辑空间开始,而不仅仅是窗口空间。 (2认同)
  • 整个答案为+ 1,*为-1(等待,而不是-2),这是因为我们从右手到左手的方式是因为正向向量在gluLookAt()的标准实现中被求反每个人都使用的函数来创建视图矩阵。对正向向量求反时,具有改变坐标系的惯用性的作用。“ *,这仅仅是垃圾... (2认同)
  • ...在`gluLookAt` 计算中否定前向向量与改变坐标空间的手性无关,这就是这个矩阵的计算方式(实际上 +z 在右手中确实是 *"backward"*空间)。`gluLookAt` 除了在右手空间中计算一个普通的刚体变换(旋转+平移)之外什么都不做。正如您在回答中已经指出的那样,固定函数管道(通常也由着色器)使用的投影矩阵在对 z 分量的否定中执行实际的手性变化。 (2认同)
  • @bobobobo 你说如果你只使用旋转和平移函数来计算你的视图矩阵(我猜你不会指责改变手性),而不是`gluLookAt`,那么`gluLookAt`不会改变基础一?绝对不是(因为你可能知道不是 *"everybody"* 使用 `gluLookAt` 进行视图矩阵计算),因为你应该知道 `gluLookAt` 只做一堆旋转和平移调用(它们甚至伪装成*“高水平”* 术语 *“基础变化”*) 绝对不涉及任何反射。 (2认同)

hul*_*ist 25

默认情况下,规范化设备坐标是左撇子.

glDepthRange默认为[0,1](近,远),使+ z轴指向屏幕,+ x向右,+ y向上是左手系统.

将深度范围更改为[1,0]将使系统右撇子.

引用Nicol之前的回答 :(罢工是我的工作,下面解释)

我很惊讶没有人提到过:OpenGL也适用于左手坐标系.至少,当您使用着色器并使用默认深度范围时,它会执行此操作.

一旦你抛出固定功能管道,你直接处理"剪辑空间".OpenGL规范将剪辑空间定义为4D齐次坐标系.当您通过规范化的设备坐标和向下到窗口空间进行变换时,您会发现这一点.

窗口空间位于窗口像素的空间中.原点位于左下角,+ Y向上,+ X向右.这听起来非常像右手坐标系.但是Z怎么样?

默认深度范围(glDepthRange)将近Z值设置为0,将远Z值设置为1.所以+ Z 离开了观众.

这是一个左手坐标系.是的你可以将深度测试从GL_LESS更改为GL_GREATER和将glDepthRange从[0,1]更改为[1,0].但是OpenGL 的默认状态是在左手坐标系中工作.并且从剪辑空间到达窗口空间所需的变换都没有否定Z.所以剪辑空间,顶点(或几何)着色器的输出是一个左手空间(有点.它是一个4D均匀空间,所以很难确定用手).

在固定功能流水线,标准投影矩阵(由glOrtho,glFrustum等产生的)中的所有从右旋空间变换到左手之一.他们颠覆了Z的意思; 只需检查它们产生的矩阵.在眼睛空间中,+ Z向观察者移动; 在后投影空间中,它会移开.

我怀疑微软(和GLide)根本没有在他们的投影矩阵中执行否定.

因为它偏离了我的发现,我确实打了一个部分.

更改DepthRange DepthFunc并使用ClearDepth(0)可以正常工作,但是当使用它们时,它们会相互抵消回到左手系统.

  • @SigTerm为什么你认为纠正错误陈述是不值得的?我花了几个小时来排除顶点坐标和矩阵旋转生成,以发现默认坐标系实际上并不是右手. (3认同)

ZK_*_*ZK_ 11

只有NDC

你应该只注意到它__CODE__,它是一个左手坐标.无论你使用什么坐标,左手,右手轴坐标等都需要镜像到NDC.如果你愿意,你可以完全用左坐标书写世界空间.

为什么我们在世界空间中使用右手坐标?

我认为它是常规的.它就是这样.也许它只是想与DirectX区别开来.

  • OpenGL早于DirectX几年,所以OpenGL肯定不会试图将自己与DirectX区分开来.DirectX的首席开发人员Alex St. John表示,微软决定采用左撇子协调系统"部分出于个人偏好"和"任意选择". (4认同)
  • 我认为这还不够重复。所有这些显示“建模转换”,“视图转换”,“透视转换”的图都无法表明它们不是OpenGL的固有部分。您甚至可以在有或没有着色器,有或没有矩阵的情况下手动进行所有变换。 (2认同)
  • 如果重复它以包括"标准化设备坐标"这个词可能会更好. (2认同)

Hei*_*aen 7

Kouichi Matsuda撰写的"WebGl编程指南"在"WebGl/OpenGl:左手或右手?"上花费近十页.

根据这本书:

  • 在实践中,大多数人使用右手系统

  • OpenGl实际上是一个内部的左手系统

  • 在内部,更深层次,它实际上都没有.在最底层,OpenGl并不关心z值.绘制图形的顺序决定了在顶部绘制的内容(首先绘制三角形,然后绘制四边形,四边形覆盖三角形).

我并不完全同意"它既不是",但这无论如何都可能是一个哲学问题.

  • `绘制图形的顺序决定了在顶部绘制的内容(首先绘制三角形,然后绘制四边形,四边形覆盖三角形).在没有深度测试的情况下,这是正确的.在存在深度测试的情况下,将片段的z值与深度缓冲区中的值进行比较,如果深度测试失败则丢弃片段,因此四边形可能会也可能不会覆盖三角形,具体取决于它们的深度和使用深度函数. (5认同)