为什么DirectX使用左手坐标系?


52

我考虑过在Stack Overflow上发帖,但是这个问题使我感到主观,因为我认为微软在此问题上的选择没有合理的技术解释。但是这个问题困扰了我很久了,这个问题在我的一个项目中不断出现,而我却从未真正尝试过解释这个问题:

OpenGL使用右手坐标系,其中世界坐标系的+ Z部分向观察者延伸。

DirectX使用左手系统,其中世界坐标的+ Z部分延伸屏幕中,远离查看器。

我从未使用过Glide API,所以我不知道它是如何工作的,但是据我所知,它也使用了左手系统。

是否有技术原因?如果不是,那么坐标系的特定惯用性在概念上是否有优势?为什么一个选择另一个?


5
这似乎是在问为什么阿拉伯语和希伯来语是从右到左书写的,而其他所有语言都是从左到右书写的。
加布

17
我只是想了解为什么图形API之间存在如此明显的不一致,而图形API在数学上有着坚实的基础。犹太字母的方向绝对不是建立在不变的规则之上的。
greyfade11年

3
为什么我们不雇用.NET程序员(2011-03-25)中提到了此问题。
彼得·莫滕森

2
OpenGL和Direct3D都不是纯左撇子。前者在剪辑空间中变为左手,而后者的屏幕空间为右手,即在D3D的屏幕空间中,从+ Z侧看​​时,从X到Y的旋转是逆时针旋转。AND这两个系统都允许开发人员使用两个手性空间。
legends2k 2013年

1
@PeterMortensen非常有趣的是,.NET的所有憎恨者甚至都不知道它是什么。他们可能指的是ASP.NET Webforms框架。.NET可以描述为基类库和CLR。
松饼人

Answers:


64

我知道这是一篇过时的文章,但我看到该文章已被引用并且不喜欢所选答案的语气。

所以我做了一些调查!

  1. DirectX是旧的。它于1995年首次发布,当时世界上不止NvidiaATI,还有DirectX和OpenGL。人们已经超过15年了。
  2. 3dfx Interactive的 Glide(当时是DirectX的竞争对手之一。当时的OpenGL并非用于游戏)使用左手坐标系。
  3. POV-RayRenderMan(皮克斯的渲染软件)也使用左手坐标系。
  4. DirectX 9+可以同时使用两个坐标系。
  5. 无论WPFXNA(这与DirectX场景下工作)使用右手坐标系。

由此,我可以推测出几件事:

  • 行业标准并不像人们喜欢的那样标准。
  • Direct3D是在每个人都以自己的方式做事的时候构建的,而开发人员可能并不了解。
  • 惯用左手是可选的,但在DirectX世界中是惯用的。
  • 由于约定难以解决,因此每个人都认为DirectX只能用左撇子操作。
  • 微软最终学习并遵循了他们创建的任何新API的标准。

因此,我的结论是:

当他们不得不选择时,他们不了解标准,选择了“其他”系统,其他所有人也都参与其中。 没什么可做的事,只是不幸的设计决定,因为向后兼容性是微软游戏的名称。


11
与3D计算机图形学相比,DirectX还是婴儿服装,与必须管理多个3D坐标系并在其中进行变换的计算机程序相比,DirectX相对年轻。那是在1970年代中期,我第一次参加图形课,甚至教练(Frank Crow)都极力要求我们仅使用右手坐标系。1983年,我从事的工作是没有图形,但确实进行了坐标转换,并且强制性的右手规则是FIRST项目备忘录。(而且我没有发出!)
John R. Strohm

7
我不确定年龄与年龄有关。大多数物理科学都没有使用右手坐标系,并且比计算机存在的时间长了很多年吗?我要说的是,这比Glide和DX遵循的约定要古老得多。
Thomas Owens

3
仅仅因为在学术界使用的标准并不意味着在工业/其他应用中它将是相同的。毕竟,人们会遵循自己领域中正在使用的任何东西。否则,图形系统的原点应位于屏幕的左下角,而不是左上角。另外,关于年龄的观点是,DX是在整个“桌面3D渲染”还很新的时候诞生的,而“标准”和“最佳实践”尚未完全敲定。
Kyte

1
a)因此,您称呼我的答案,这是可证明事实的简单清单,而当您自己提供的产品是对公司行为不当的指控,没有引文或支持什么?b)如果您不喜欢我的回答,则可以随时给出自己的答案。当我给出这个答案时,被接受的答案已经是一岁了。如果您觉得自己有贡献,可以自由添加更多的知识。c)当您在市场上的地位不稳定时,很难建立垄断地位。这不是现代的跨国公司。
凯特,2012年

2
@Kyte 3Dfx出于特定原因具有专有的API,以将您锁定在其硬件中。他们强迫最终用户购买其硬件,因为开发人员被“贿赂”以编写仅适用于3Dfx的游戏。微软希望将您锁定在他们的API中,以便开发人员只为Windows编写游戏,这最终使3Dfx丧命。简单明了的业务决策,不会出现不良行为。今天仍在继续。Nvida希望您使用CUDA将您锁定在他们的卡中,AMD希望使用OpenCL,2012也是该行为背后的原因。这是历史,我当时在行业中。

37

我很惊讶没有人提到:OpenGL也可以在左手坐标系中工作。至少在使用着色器并使用默认深度范围时,它才起作用。

一旦淘汰了固定功能管道,就可以直接处理“剪贴空间”。OpenGL规范将剪辑空间定义为4D同构坐标系。当您通过归一化的设备坐标进行转换时,一直到窗口空间,都可以找到。

窗口空间等于窗口像素的空间。原点在左下角,+ Y向上,+ X右侧。这听起来很像一个右手坐标系。但是Z呢?

默认深度范围(glDepthRange)将Near Z值设置为0并将far Z值设置为1。因此,+ Z 远离观看者。

那是左手坐标系。是的,您可以将深度测试从GL_LESS更改为GL_GREATER,并将glDepthRange从[0,1]更改为[1,0]。但是OpenGL 的默认状态是在左手坐标系中工作。而且,从剪贴空间进入窗口空间所需的任何变换都不会使Z取反。因此,剪贴空间中,顶点(或几何)着色器的输出是一个左手空间(kinda。这是一个4D均匀空间,因此很难确定惯用的惯用语)。

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

我怀疑微软(和GLide)根本没有理会在他们的投影矩阵中进行求反。


4
确实很有趣。我承认,我从来没有仔细看过。当我的问题特别涉及世界空间时,您的回答让我深思。
greyfade 2011年

我发现更改深度范围或深度测试可以使它成为惯用右手,但同时使用这两者可以互相抵消,从而使我成为惯用左手的系统。
hultqvist 2012年

1
有趣的。看一下视口深度转换:z_wiewport = z_clip *(远近)/ 2 +(近远)/ 2。这使得剪辑空间的-1映射到near,而+1映射到far。因此,即使您以后仍可以反转将其映射到视口的方式,剪辑空间本身也可以视为左移
科斯2012年

1
@NicolBolas:您是否注意到Direct3D并不是纯左撇子,因为它的屏幕空间是右撇子?X从左到右,Y从上到下,Z远离观察者,即从Z轴的相反方向观察时,X到Y是逆时针旋转。
legends2k 2013年

1
@bobobobo “我注意到由gluLookAt生成的视图矩阵也可以改变惯用性” -不,不是。这就是正向向量的计算方式,但是此矩阵仍然是惯用右手空间中的普通刚体变形(实际上,+ z确实在惯用右手空间中为“后向”)。否定正向向量与更改坐标空间的惯性没有任何关系。
克里斯说莫妮卡

11

这是纯粹的历史。在远古时代,早期的洞穴图形学程序员将监视器(电传打字机?石头打字机?)的视线表面视为二维方格纸。在数学和工程学中,在方格纸上绘制数据点的常规约定是:x =正确,y =向上。然后有一天,大约在发明硅轮之后的一个星期,有人想到了3D图形。当这个想法的蜡烛灯泡在他们头顶上方闪烁时,无论出于何种原因,他们都选择在观看者之外添加Z =。(哎呀,我的右手只是想像而已。)

他们不知道有一天他们的后代会成为工程师,科学家,美术师,商业艺术家,动画师,产品设计师等,并发现3D图形很有用。所有这些优秀的现代人都使用右手坐标系来彼此保持一致,并建立了更为成熟的数学课本和物理学惯例。

将3D坐标系建立在显示表面上是愚蠢的。它是最重要的模型-描述房屋,椅子,超重的绿色食人魔或星系的三角形,多边形和平面。如今,我们所有人都在右手XYZ系统中设计和建模东西,并且就模型的世界而言,甚至在考虑如何渲染之前都进行设计和建模。相机是在某个时候添加的,可能以疯狂的方式四处飞行,并且它是不可见的基础设施,可将模型转换为必须在其肠道内通过协调系统变换来摆弄的像素。

只是增加了混乱,一些图形库认识到CRT从上到下扫描图像,因此Y = down。即使在今天,所有的窗口系统和窗口管理器(X11,fvwm,gtk +,Win31 API等)也都使用了此功能。像Clutter,Beryl等新型3D GUI系统如何处理Z,是3D图形建模的另一个问题。这只涉及应用程序程序员和GUI设计人员。


1
一切都非常有趣,这无疑解释了SGI GL背后的原理。...但是这如何解释DirectX惯用左手?
greyfade 2010年

几个2D和3D系统都从共同的历史中得出了它们的约定。
2011年

10

它们基本上是等效的,因为一个很容易转换为另一个。对于左手系统,我可以发现的唯一优势是:由于对象在任何方向(x,y或z)上都距观察者较远,因此距离是一个较大的值。但是我不知道这是为什么微软选择了一个而不是另一个。

POV-Ray还使用左手坐标系。


5
是的,我认为许多图形新手都认为z随屏幕深度的增加而自然增加。但是他们也希望x向右增加而y向上,即“图形轴”样式。这使他们成为左手坐标系。直到后来,当他们尝试做更复杂的事情时,他们才意识到,他们与科学,数学,工程学的右手世界不合时宜。
2010年

6
@Timday,您必须教新手有关秘密3D图形非握手的知识。伸出右手,拇指,食指和中指彼此成直角。拇指是X,食指是Y,中指是Z。现在移动您的手,使其与所需的任何坐标对齐,您将立即知道运动将如何影响转换。
约翰·R·斯特罗姆

3
@约翰:嘿,你猜怎么着,物理学家也有同样的秘密握手!
2010年

1
@John尽管我完全同意右手系统的优点,但是您知道您的握手规则(每个人都应该在学校学习过)也可以用左手来使用左手系统。
克里斯说,请

@ChristianRau,您使用哪只手取决于您要描述的坐标系是右手还是左手。
约翰·R·斯特罗姆

10

DirectX(和Direct3D)的首席开发人员Alex St. John最近对此发表了评论。在一篇有关Direct3D历史的文章中,他写道:

要求我选择Direct3D API的惯用方式。我选择了一个左手坐标系,部分是出于个人喜好。[...]这是一个任意选择。

资料来源:http : //www.alexstjohn.com/WP/2013/07/22/the-evolution-of-direct3d/


仅当您不知道世界其他地方在做什么时,这是一个任意选择,而世界其他地方实际上已经在图形的右手坐标系上进行了标准化。
John R. Strohm

1
@ JohnR.Strohm-您甚至看过链接的文章吗?
Maximus Minimus

Link-rot已经吞噬了该页面。以下是最新的工作快照:web.archive.org/web/20161101112002/http://www.alexstjohn.com/WP/...
最大巴勒克拉夫

5

要了解的是,浪费了大量的程序员时间,在左手坐标系和右手坐标系之间进行转换,并且浪费更多的程序员时间来记住在任何特定时刻都需要哪个系统。

当右手坐标系成为行业标准时,所有这些都消失了。

已经有足够的常用坐标系,而不会通过引入惯用性问题使坐标系数量加倍。参见Minkler&Minkler,“航空坐标系和转换”。如果您从事航空坐标业务,例如进行飞行模拟,则需要该书。

我的猜测是,Microsoft在DirectX项目上没有任何人了解行业标准,没有意识到存在行业标准,因此认为没有关系。

他们知道惯用右手的系统是行业标准的另一种可能性,他们故意使DirectX用惯了左手,从而使人们很难将使用DirectX的代码转换为使用OpenGL的代码,这没有考虑。如果我发现确实如此,我会发现有必要在雷德蒙德从事一个新的,可能是短命的职业,担任斧头杀手。


我不想在我的问题上抨击微软,所以我不想提及它与他们所考虑的OpenGL不兼容的可能性。
greyfade

3
@greyfade:好的,让我这样说。没有任何技术上的原因比左手坐标更喜欢左手坐标,反之亦然。但是,如今有非常非常好的理由偏爱惯用右手的坐标,并且喜欢柏油,羽毛和在铁路上骑行出行的人,甚至低声暗示完全使用惯用左手的坐标进行任何操作的提示。这样更简单吗?
约翰·R·斯特罗姆

我不知道我可以为此集结任何义愤。在我的工作中,我相当定期地使用PostScript(坐标从[0,0]左下角开始,最大值从右上角开始),因此坐标转换只是这里生活的一部分。
Inaimathi 2010年

2
嗯,这是100%的猜测吗?为什么将其标记为答案?
Factor Mystic

3
击败我,这只是毫无意义的咆哮,而且具有讽刺意味的是,就像左手坐标系一样,很多人出于某种原因而接受了它。
快速乔史密斯

5

对于所有认为右撇子或左撇子没有优势的人,您绝对是错误的。直角坐标系的右手性来自矢量叉积的定义。对于XYZ基向量uv并且ww = u X v

这个定义对于矢量数学,矢量微积分以及许多物理基础都是至关重要的。假设您正在尝试模拟电磁相互作用。您有一个磁场矢量,M并且一个带电粒子在该场中以速度运动v。充电会以哪种方式加速?容易朝方向前进M X v。除了一些白痴以为,将显示系统放在左手会很有趣,因此它会向方向加速-M X v

基本上,两个矢量量之间的任何物理相互作用都定义为右旋,因此,每当您需要模拟这种相互作用时,最好希望您的图形系统是右旋的,否则您将需要记住在负数中你所有的数学。


电磁不是产生叉积的唯一地方。它也出现在空气动力学和轨道力学中。飞行仿真必须处理它,这就是物理坐标系和图形坐标系碰撞的地方。参见上面我的回答中引用的Minkler&Minkler。
John R. Strohm 2012年

@汤姆:我不确定这是否正确;取3个向量,例如(1、0、0),(0、1、0)和(0、0、1),执行ixj得出k,因为叉积的公式是定义明确的,并且数字没有任何乘积手性/手性;只有人类以某种惯性来解释这三个向量,即使这样,我们仍可以选择用两种惯性来解释它,并且仍然是一致的,即在惯用左手的ixj = k中而惯用惯用在右手的ixj = k将走向。提醒您,我也是一个惯用右手的人,但这仍然是事实。
legends2k 2013年

@ legends2k:是的,我想这是对的,只要您根本不希望数字表示任何意义。只要您希望数字代表物理交互作用或显示系统中的坐标,或者实际上什么都没有,那么它就非常重要。
汤姆(Tom)

@Tom是对的,我们必须赋予数字含义。那真的很重要。但这仍然不是说左手在右手之上的理由。我可以给一个意义0,0,1的前进,这是左侧如此1,0,0 X 0,1,00,0,1是左手
Thaina

@Tom实际上,当在左手坐标系中进行物理操作时,公式仍然是,M X v但是磁场M被认为指向相反的方向,因为它是伪矢量。您可以在两个系统中使用相同的方程式:唯一改变的是您对伪矢量“指向”的方式的解释。诸如加速度之类的适当矢量在任何一个坐标系中都将始终相同。en.wikipedia.org/wiki/Pseudovector#The_right-hand_rule
奥斯卡·本杰明

5

Direct3D早期左手惯用性的真正答案要比你们中某些人所想的要险恶得多。DirectX始于微软在1995年收购RenderMorphics时。

当时,RenderMorphics办公室使用的标准图形文字是Newmann和Sproul的“交互式计算机图形原理”,它使用左手坐标进行所有操作。这是我上大学时使用的同一本书。查看D3D代码,您甚至可以使用与本书中的方程式匹配的变量名来查看它们。

这不是微软的阴谋。这个决定是在微软还没有出现之前就做出的。


我同意这里的评论,这听起来像是一个城市传奇,但是很高兴得到您的个人见解。
Josiah Yoder

3

两者最终都不会比另一个更好-将3D坐标映射到2D曲面,因此可以任意选择指向观察者或进入屏幕的第三个尺寸(实际上使物体变成3D)。无论如何,您都将通过4x4矩阵进行处理,因此没有技术上的理由选择一个。从功能上讲,人们可以争论:

  • 在计算和其他领域,X轴从左到右一直是一个相当广泛的共识(航空显然是一个明显的例外)。
  • 在数学中,Y轴指向上方。(另外,上升就是气泡的所在)。
  • 在计算机显示器上,Y轴指向下方(因为这是CRT屏幕的工作方式,也因为这是大多数人工脚本排列行的顺序)。
  • 当您查看X / Y平面中某个表面的“可见”侧时,法线应该指向查看者(例如,当您查看卫星素材时;“海拔高度”指向卫星,而不是指向地球中心)。由于X / Y平面的法线是Z轴矢量,因此Z轴也应指向观察者。
  • 当您在计算机屏幕上查看3D图像时,离查看器较远的点应具有较大的Z分量。因此,Z轴应指向屏幕。

结论:X轴存在一些共识,但对于其他两个轴,两个方向均可辩驳,产生两个右手构型和两个左手构型,并且它们都是有意义的。


3

有趣的事实。

Direct3D(不是DirectX-DirectX还涵盖输入,声音等)实际上没有左手坐标系。

它完全能够支持RH和LH系统。如果您查看SDK文档,则会看到诸如D3DXMatrixPerspectiveFovLH D3DXMatrixPerspectiveFovRH之类的函数。两者都起作用,并且都产生一个投影矩阵,可以成功地与您选择的坐标系一起使用。地狱,如果愿意的话,甚至可以在Direct3D中使用column-major。它只是一个软件矩阵库,您无需使用它。另一方面,如果要在OpenGL中使用它,您会发现它也可以与OpenGL完美配合(这也许是矩阵库独立于Direct3D本身的权威证明)。

因此,如果要在程序中使用RH系统,只需使用该功能的-RH版本。如果要使用LH系统,请使用-LH版本。Direct3D不在乎。同样,如果要在OpenGL中使用LH系统-只需glLoadMatrix一个LH投影矩阵即可。这些东西都不重要,而且与您有时看到的巨大问题相距不远。


0

任何一种习惯都没有技术优势,这完全是任意的。只要您保持一致,两者都可以正常工作。

由于一致性的优点,理想的情况下,应该只“使用其他人正在使用的东西”,但这在许多情况下是相当困难的,因为在实践中也没有压倒性的“首选”约定:两种惯用语都被广泛使用。最好情况下,某些社区(例如OpenGL)之间存在一定的一致性。

因此,我认为这个问题的基本答案是:他们选择了他们所选择的东西,因为它感觉正确(毫无疑问,他们以前有过这种手法的经验),并且没有理由不这样做。

最终,这没有什么区别-任何认真地想要与其他系统/社区交换资产/代码的人都将不得不准备应对反手转换,因为这是3D图形中不可或缺的事实。


0

将其作为我以前的回答的补充材料。根据1990年代的旧OpenGL规范:

OpenGL不会在其任何坐标系上强制左旋或右旋。

(来源:http : //www.opengl.org/documentation/specs/version1.2/opengl1.2.1.pdf)。

因此,既然D3D和OpenGL都不强制使用任何惯用语,那么真正的问题是:为什么人们认为这有什么大不了?


1
为什么将它张贴在单独的答案中?我的意思是您可以编辑以前的答案来添加吗?
t

-1

我不愿告诉您,但是一组坐标的“手”实际上是主观的-它取决于您以何种方式看待事物。来自OpenGL立方体贴图规范的一个示例:如果您想在立方体内部看,则坐标系是左手的,如果您想从外部看,则是右手的。这个简单的事实会带来无尽的痛苦,因为要获得一个数字正确的答案,您的所有假设都必须是一致的,即使在本地并不实际影响您做出哪个假设。

OpenGL规范正式是“中性的”,并且竭尽全力避免出现此问题,也就是将其推迟给程序员。但是,眼睛坐标和剪辑坐标之间存在“手变”:在模型和眼睛空间中,我们正在查看,在剪辑和设备空间中,我们正在向外查看。毫无疑问,我总是在为这种意外并发症的后果而苦苦挣扎。

叉积是我们的朋友,因为它使您可以从一对向量生成绝对的右手或左手3D坐标系。但是这取决于哪一手,您将其称为“ X”。


3
叉积是反交换的。A x B ==-B xA。这样,叉积定义为采用非共线的第一向量和第二向量,该向量以该顺序书写,并产生垂直于包含第一和第二向量的平面的第三向量。 ,以及在按顺序枚举矢量(第一,第二,结果)时适合创建右手坐标系的方向。如果您选择变态,请放心,但要警告:如果在我周围这样做,则最好从城外乘火车欣赏屁股中的柏油,羽毛和碎片。
John R. Strohm

约翰说得很对。但是您仍然必须面对这样的事实,即可能发生这种变态,这意味着不存在“绝对右手性”之类的东西,这意味着您和我仍然需要正确地确定信号。
Thomas Sharpless 2013年

-3

我可以说行业标准从一开始就是错误的

坐标的行业标准实际上来自于桌面坐标,即人们在桌子上绘制所有东西时,这是水平面。X是左/右,Y是前/后,所以它只是使Z向上而已,因此诞生了右手坐标系

但是您知道我们现在在监视器屏幕上使用的是垂直平面。X仍然是左/右,而Y是上下

那么什么是右手坐标系呢?它使+ Z向后,-Z向后,这到底是什么?上是+下是-右是+左是-但前进是-和后退是+ ??? 如果我们制作游戏角色在3D世界中运行,那真是太愚蠢了,但是我们需要减z才能前进。这就是游戏程序员最欣赏DirectX的原因

从一开始,要从桌面获取标准并在监视器上使用它是非常错误的。现在,我们应该承认,OpenGL和Industry都是错误的。他们只是使用他们认为会让自己感到舒适的东西,但他们是错的,右手坐标系只是一个垃圾遗产,应该尽快扔掉


2
-1为无知。右手惯例来自物理学和数学,特别是矢量叉积运算,这是电磁场理论和力学的基础。计算之所以采用它,是因为最初使用计算机是为了处理数字。
John R. Strohm 2013年

对于您的无知应该改为-1。正如我所说的,过去的“桌面坐标”物理和数学始终在桌面而不是显示器上运行,所以我称其为“桌面坐标”是因为您在水平桌面上计算物理和数学
Thaina 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.