it-swarm.cn

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

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

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

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

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

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

52
greyfade

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

所以我做了一些调查!

  1. DirectX是。它于1995年首次发布,当时世界上不只 Nvidia[〜#〜] ati [〜#〜] , OpenGL。人们已经超过15年了。
  2. 3dfx Interactive的 Glide(当时是DirectX的竞争对手之一。当时的OpenGL并非用于游戏)使用左手坐标系。
  3. POV-RayRenderMan (Pixar的渲染软件)也使用左手坐标系。
  4. DirectX 9+可以同时使用两个坐标系。
  5. [〜#〜] wpf [〜#〜][〜#〜] xna [〜#〜] 场景)使用右手坐标系。

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

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

因此,我的结论是:

当他们不得不选择时,他们不知道标准,选择了``其他''系统,其他所有人也都去兜风了。没什么可做的事,只是不幸的设计决定,因为向后兼容性是微软的游戏之名。

64
Kyte

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

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

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

默认深度范围(glDepthRange)将Near Z值设置为0,将far Z值设置为one。因此+ Z会从查看器开始away

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

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

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

37
Nicol Bolas

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

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

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

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

11
DarenW

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

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

10
tcrosley

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

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

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

10
Daniel Rikowski

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

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

已经有足够的常用坐标系,而不会通过引入惯用问题来使坐标系增加一倍。参见 Minkler和Minkler,“航空坐标系和转换” 。如果您从事航空航天业的业务,例如飞行模拟中,您[〜#〜]需要[〜#〜]那本书。

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

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

5
John R. Strohm

Direct3D早期左撇子的真正答案要比你们中的某些人想像的要少得多。 DirectX始于微软在1995年收购RenderMorphics时。

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

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

5
Stephen Coy

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

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

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

5
Tom

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

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

结论:X轴存在一些共识,但对于其他两个轴,可以争辩两个方向,产生两个右手配置和两个左手配置,并且它们都有意义。

3
tdammers

趣味事实。

Direct3D(不是DirectX-DirectX还包括输入,声音等)具有左手坐标系。

它完全能够同时支持RH和LH)系统。如果您查看SDK文档,您会看到D3DXMatrixPerspectiveFovLH and D3DXMatrixPerspectiveFovRH之类的功能。生成可以成功用于所选坐标系的投影矩阵。地狱,如果愿意,您甚至可以在Direct3D中使用column-major;它只是一个软件矩阵库,不需要使用它。另一方面,如果您想将其与OpenGL一起使用,您会发现它也与OpenGL完美兼容(这也许是矩阵库独立于Direct3D本身的权威证明)。

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

3
Maximus Minimus

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

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

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

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

0
Maximus Minimus

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

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

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

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

0
snogglethorpe