Direct3D 的进化史

伯乐在线导读:本文作者 Alex St. John 和 Craig Eisler、 Eric Engstrom 三位一起创建了早期的微软 DirectX 技术平台。1992-1997年Alex在微软的工作,后来成为 DirectX 技术布道师。感谢@浅水清流的热心翻译。如果其他朋友也有不错的原创或译文,可以尝试推荐给伯乐在线

我在Direct3D上工作了很多年,多年来技术有了极大的发展。多年来,现代图形处理器(GPU)发生了巨大的变化,拥有了我曾经以为在有生之年不可能见到的运算速度和能力。现代GPU的演变是在很多充满魅力的市场驱动下进行的,其中我觉得最重要并且有趣的是,在Direct3D的影响下,新一代的GPU支持数以千计的处理核心,数十亿晶体管(超过CPU)而且在大多数应用中都要快很多倍。我可以讲很多关于D3D的趣闻和政治传说,但是我更想记录下D3D的由来以及对现代GPU架构的深远影响。

本文使用的是1995年Direct3D第一次发布时的老文档。这份文档包含了对3D硬件加速架构的愿景,在很大程度上主导了现代GPU演变成为今天我们所见的强大得另人难以置信并且用途普遍的无所不在的消费型超级计算机。

D3DOVER

我进入计算图形学不是对游戏感兴趣,而是对想了解物理模拟计算。为了了解如何模拟量子力学、化学和生物系统,在20世纪80年代中后期,我开始参与Siggraph研究3D图形学。模拟光和材质互相作用在Siggraph曾经风靡一时,在此期间我学习了3D。了解3D数学和光照模拟,让我通过我在职业早期创建的PostScript RIP(光栅图像处理器),成为了在出版业的图形和色彩专家。我曾经和剑桥大学的工程师一起开发了在连续色调印刷发明之前印刷彩色图形的软件方案。我的专业背景获得了微软的青睐,在1990年初我获邀参与为Windows 95和Windows NT重新设计具备与当时表现卓越的苹果竞争的能力的打印架构。峰回路转之后,我的职业生涯到了回到3D的时候,我开始主动和几个朋友为Windows重新设计支持实时游戏和视频架构的图形和多媒体架构,这最终导致游戏成为了微软的一个重要战略。在索尼推出3D游戏机PS1之后,为Windows找个一个3D解决方案,成为了负责开发Directx的我们义不容辞的责任。

对我来说,制定微软在游戏市场3D战略的挑战是一个经济问题。微软应该采取什么样的策略,去创建一个充满活力竞争激烈的市场给消费者带来实惠并且引导未来的发展。在那个时代,3D实时渲染的复杂度远远超出了当时的硬件能力,找出一个远离数学的理想方案让任何hack都能构建出足够好的3D应用看起来是不可能,我们有希望改变世界。

当时唯一的商业解决方案是为CAD设计的3D硬件。这些工作站需要花费数十万美元。虽然OpenGL API 是当时市场上唯一的3D API标准,但是它并不是为3D游戏设计的。例如,纹理映射是渲染逼真的图形的一个重要技术,但是CAD优先考虑的是功能而不是看起来cool。同样,丰富的动态光影效果对提高游戏的表现力很重要,但是对CAD并不重要。而高精度的模型对于CAD重要,但是对游戏并不重要。最重要的是OpenGL并没有为实时高度互动的图形而设计的离线缓冲区来避免渲染过程中撕裂纹理。这并不是说OpenGL并不能适应这些游戏所需的特性,而是它的实际市场是昂贵的工作站而不是$200的游戏显卡。

在20世纪90年代计算机的RAM非常昂贵,正因为如此,早期消费型显卡选择了内存需求最小的方案。Sony在优化PS1的3D硬件时,没有依赖内存密集型的Z-buffer,而是使用多边形区域排序算法,虽然会在活动的骨骼间产生丑陋的交点。“画家算法”对3D渲染来说非常快速,并且几乎不要额外的内存。对于游戏开发来说这是一个丑陋而务实的做法,但是这种做法对CAD来说是不可接受的。

在制定Direct3D架构时,我们面临的类似艰难选择不胜枚举。我们希望当时领先的显卡厂商,ATI、Cirrus、Trident、S3、Matrox 和其他厂商能彼此竞争,快速更新3D显卡,而无需在一片混乱中建立市场。微软的OpenGL团队信赖Michael Abrash的技术方案,一个被称为3DDDI(3D Device Driver Interface)的驱动程序模型。3DDDI是一个非常简单的驱动模型,只支持硬件加速3D光栅化。3D场景光照变换的复杂数学运算被留到了CPU。3DDDI使用“功能位”来指定额外的渲染功能(比如过滤),消费型显卡厂商可以选择实现一部分。3DDDI的问题是在邀请游戏厂商参与时,事情失去了控制。这么多“功能位”,游戏厂商要么选择支持各种“未知”的硬件特性,利用一切可能的方式充分挖掘显卡的能力(硬件厂商可能会选择支持不同的硬件特性导致用户的硬件配置难以预测,为了在任何设备上都良好的表现,游戏将不得不准备大量的美术资源)或者游戏只使用一组所有硬件都支持的简单常见的3D特性,但是没有硬件公司提供的最新特性,在市场上就会缺乏表现力。OpenGL的人在微软没有意识到这是个大问题,因为在他们的世界里,所有人都使用支持他们需要的所有特性,价值$100,000的昂贵工作站。

认识到我们不可能从OpenGL团队得到我们想要的东西之后,我们决定创建一个新的,只为游戏而设计的3D API。这些API什么都不做,但是我们需要通过制定明确的驱动程序架构,来创建一个竞争激烈而有序的市场。在这方面,D3D API不是OpenGL API的替代品,它是一个驱动API,创造出来的一个经济战略目的,是引导消费型显卡市场进行激烈而有序的竞争。换句话说,D3D API更多出于经济目的,而不是技术目的。在这方面D3D API的几个革命性的有趣之处是,API什么都没有做,而是制定它所依赖的驱动程序架构。

当我们决定收购一只团队打造Direct3D时,我被特许参与评审候选企业是否有足够的技术能力帮助我们制定我们所需要的API。正如我以前所说,我们考核了Epic Games ( UnReal 引擎厂商), Criterion (后来被EA收购), Argonaut 和 Rendermorphics。我们选择了总部设在伦敦的Rendermorphics,因其创始人Servan Kiondijian对如何设计一个尽可能兼具兼容性和创新的3D驱动程序架构有一个非常明确愿景。Direct3D的第一个版本非常的简陋,但是API迅速向在未来有巨大潜力的方向演进。

我在这一时期的主要记忆是,我作为常驻DirectX团队的3D专家,被要求为D3D选择一个坐标系标准。我选择了左手坐标系,一部分原因出于个人喜好。我至今还记得,因为这是一个轻率的决定,此后带来无数的麻烦,因为其他3D建模工具都采用了OpenGL标准的右手坐标系。当时没有人会想到,Autodesk和Maya的建模工具会成为游戏开发行业的建模的标准工具。微软已经有了收购SoftImage取代Autodesk和Maya的计划。Whoops…

早期的Direct3D HAL(Hardware Abstraction Layer) 以一种有趣的方式设计,它以垂直的3个阶段构成。

最高层是几何变换层,中间层专用于光照计算,底层进行光栅化过程,生成像素图像。这种垂直驱动架构背后的目的是让硬件厂商在实现一个相对一致的特性要求进行创新。他们可以细分他们的产品,设计更加高效的3D管线,从而获取更高的性能,并且和现有产品保持兼容,否则就会需要配置一个庞大的矩阵进行兼容性测试,或是需要大量的冗余美术资源。由于Rendermorphics创建Direct3D API时提供了一个“相当高效的”无需硬件加速的软件实现,游戏开发者可以把重心放在Direct3D API上,而无需关注无数不兼容的硬件特性组合。至少理论上是这样。可惜和3DDDI驱动程序规范一样,Direct3D仍然包含了“功能位”设计,允许加入垂直架构之外的硬件特性。虽然我极力反对让Direct3D倾向于堆积“功能位”,但是小组受到了来至微软OpenGL组的巨大竞争压力,硬件提供商支持他们。

硬件厂商为了让自己的产品可以更有优势,威胁将会支持和促进游戏厂商使用OpenGL,因为OpenGL驱动程序模型支持“功能位”,他们可以设计别人不具备的硬件特性。这很常见(现在还是),硬件厂商赞助游戏厂商使用他们与基础功能不兼容的硬件特性,迫使消费者不断更新他们的显卡来玩游戏啊厂商最新的PC游戏。游戏厂商讨厌不断变化的“功能位”,因为它们复杂并且不兼容,但是又希望通过支持“非标准”3D特性获取游戏厂商的赞助。

总的来说,我认为这种趋势破坏了PC游戏市场的健康发展,并且主张抵制这种趋势,无论OpenGL或是OEM厂商的人怎么想。我相信创建一个稳定的消费市场,比安抚OEM厂商更加重要。就是这样,我是Direct3D垂直管线的强力倡导者,我们预计随着时间的推移,只实现D3DAPI的功能将会越来越普遍。我坦白承认,这种观点隐含对在其他领域创新的重大约束,引导市场被放在Direct3D团队的第一位。

最终我的估计相对准确。Direct3D固定管线,如大家所知的,通过在DirectX 7.0上进行的健康的激烈竞争,产生了内容丰富、增长迅速的PC游戏市场。在2000年初,PC游戏市场赢来了爆发性的增长,成为了全球上最大的游戏市场。这也导致GPU体系结构此后发生了许多有趣的变化。

最终Direct3D HAL是一个光栅化驱动模型加微软的OpenGL团队所倡导的“功能位”,显卡厂商将通过加速底层渲染管线的效率和添加差异化特性与对手展开竞争。引入的垂直分层架构的结果是,促使所有硬件厂商以更接近通用CPU架构的方式添加特性到GPU中,即以一致的方式进行快速浮点计算。因此消费型GPU经过多年的发展,越来越像CPU,但是有个主要的区别。因为3D管线还是刚性的固定管线,Direct3D体系结构很少需要像CPU一样针对分支代码的优化。GPU实现惊人的性能和高度并行,很大程度上得益于Direct3D图形管线内部很少甚至根本没有分支代码。因此不是发展成为一个类似于Intel CPU那样将大量晶体管用于高效的分支预测的巨大的单片CPU核心,Direct3D的GPU拥有数百至数千简单的没有分支预测的CPU核心。他们可以达到惊人的吞吐量,以令人难以置信的速度执行,如果不遇到分支代码或是随机内存访问,流水线就不会被打断。

通过支持DirectX 7.0,GPU底层的并行计算被从游戏中隐藏。游戏开发只需要知道一些硬件比另一些硬件性能更强,但是无需关系这些如何实现。早期的固定管线取得了辉煌的成果,使几十家显卡厂商采取各种方法提高性能、降低成本而不是陷入混乱的竞争中。它的图像不够漂亮,精度也不够高,但是已经足以在2000年初创建一个活跃的游戏市场。

在我讨论现代Direct3D的演变之前,我想强调几个早期Direct3D体系结构的重要思想对现代GPU的影响。在1990年的早期到中期,RAM相对昂贵,这导致消费型显卡采用了需要RAM较少的技术。这个观点对我将来很多负面故事的(well-deserved)The Talisman 架构的影响很大。

Talisman依赖各种图形学上的tricks,尽可能的降低对显存的需求,并不是一种常规做法。为了创建一个面向大众的消费型显卡市场,Direct3D团队受到了Rendermorphics创始人做出的一个艰难选择的严重影响。我们决定采用在3D上更通用更简单但是依赖更多显存的Z-buffer,来实现更好的显示效果。Rendermorphics在使用了软件Z-buffer的Rendermorphics引擎上实现了很好的3D性能,这给了我们信心去赌注,用一个更简单通用的3D API和驱动程序模型,并且相信硬件市场和RAM的价格会降下来。

但是请注意,我们在设计的Direct3D的时候,我们没有了解到微软研究院“秘密”的Talisman计划,他们也没有预计到一小群先行者,会设计了一个新的游戏3D API标准,并且在他们奇怪倡议被部署之前启动了它。总之这是一个巨大的赌注,Direct3D为游戏开发者提供了简洁和优雅的Z-buffer,值得去冒这个险,消费型3D显卡市场在早期很难以合理的价位支持它。

尽管支持Z-buffer是一个巨大的赌注,但是我们还是有两个架构上的问题需要解决。首先是PC总线一般很慢,第二是从显卡读取数据比写入数据到显卡慢的多。这通常意味着,我们的设计API需要尽可能紧凑封装数据发送给GPU的处理,和尽可能减少,将GPU处理完的数据复制回CPU处理。这通常意味着的Direct3D API进行了优化,数据打包和发送一次完成。当然这是一个不幸的约束,因为有很多华丽的3D效果,可以通过混合CPU高效的分支预测和GPU强大的浮点运算能力达到令人难以置信的并行渲染性能。

该约束正面作用之一是,它迫使GPU向更通用的方向发展,以补偿无法有效地与CPU共享数据。恰恰相反,Intel可能希望控制总线速度的发展,因为其他协处理器越来越多的取代CPU在PC中的核心地位和功能,这对Intel是个威胁。有理由相信,Intel故意限制了PC总线性能的提高,以防他们的CPU在多媒体应用市场上出现替代品。回想一下我以前的博客,推出DirectX的主要原因是防止Intel通过虚拟化支持所有Windows多媒体应用。如果Intel采用了可以使协处理器快速共享RAM的总线架构,那么GPU不大可能如今天这样支持丰富的分支预测和浮点计算。

为了克服PC总线性能的限制,大量技术投入到了用CPU压缩和简化发送到GPU的DirectX资源,以减少总线带宽的性能限制,和尽量减少需要从GPU返回CPU的操作。早期的固定3D管线在后来造成了有趣的后果,当我们开始探索通过互联网分发3D资源。

我们认识到早期支持压缩纹理,将极大提高总线性能和降低对显存的需求,问题是在一个没有标准3D纹理格式的年代,我不想过早的将一个微软指定强加给行业。为了克服这个问题,我们抱着没有标准格式的的想法前进。这个想法是我们提出的DirectX诸多专利的一个,我们提出一个GPU可以编码和解码不明格式的纹理,而DirectX的API将允许应用程序如同原始位图一样读取和写入纹理。Direct3D驱动程序进行编码和解码,而应用程序没有必要知道驱动是如何工作的。

直到到1998年,显卡厂商开始为DirectX6.0制定高标准的3D纹理格式,我们将其中之一(S3)列入Direct3D许可。

http://www.microsoft.com/en-us/news/press/1998/mar98/s3pr.aspx

DirectX 6.0 是被列入发布版操作系统版本(Windows 98)的第一个版本。直到那时,DirectX实际上只是一个内部库,被一个Windows游戏使用。直到第一个版本的之后的第5代,DirectX才正是成为Windows API。

DirectX7.0 是最后一代依靠在DirectX2.0时代就已经奠定基础的固定管线的Direct3D API。这是Direct3D非常微妙的一个过渡期,有以下几个原因;

  • 1)原来的DirectX团队创始人都离开了,
  • 2)Talisman和微软支持OpenGL的内部原因都被否决
  • 3)微软带来了游戏行业的资深人士,如Blackley、Kevin Bacchus、Stuart Moulder等进入公司高层
  • 4)游戏已经成为公司的战略重点

DirectX 8.0是Direct3D一个迷人的标志性过渡版本,因为Talisman项目的失败和OpenGL支持战略的利益受损,许多3D开发人员从这2个项目加入到Direct3D的工作中来。这个结果是非常有趣的。现在回头看,我不会做出和他们一样的选择,但是回想起来,在我看来一切都以最佳方式在工作。

Direct3D 8.0以几个有趣的方式影响了20世纪末的显卡市场。微软在很大程度上统一对OpenGL的结论,并且发现自己发展Direct3D要比Kronos的集团标准委员会推动的OpenGL要快。随着SGI死亡,OpenGL标准的控制落到了那些希望标准允许创造差异化竞争和迫使微软支持他们想推动的3D特性的3D硬件OEM的手里。最后的结果是,Direct3D和OpenGL变得更加复杂,他们在此期间趋于收敛。从DirectX8.0到DirectX11.0,游戏开发商停止采纳新的3D特性。创建游戏引擎变得如此复杂,以至于市场上只剩下几家领先的引擎开发商,包括Epic的Unreal Engine和id Software公司的Quake engine。

如果我一直在Direct3D工作,我会坚决抵制微软被3D显卡OEM厂商牵着鼻子追逐OpenGL的特性,而是专注于让游戏开发商有一致的品质和消费体验。我会反对引入shader,保持尽可能垂直整合硬件厂商之间的功能,以确保符合Direct3D驱动程序层的支持。同样,我也强烈反对放弃支持DirectDraw。3D的家伙们失去了控制,并且认定采用3D API之后不会有人需要纯2D的API,没有认识到简单的2D API满足了大量需求而且易于使用,毕竟大多数开发者不是天才,并不能轻松理解和使用3D API。强制市场接受3D API造成了巨大的准入门槛。微软后来发现了这一错误,并且从新引入了DirectDraw,也就是新的Direct2D API。基本上 Direct3D 8.0 的天才设计让它辉煌,强大并且对普通开发人员没用。

在DirectX 8.0开始开发时,我正在创办我的第一家公司WildTangent Inc,并且不再关注DirectX3D的进展。然而,几年之后我回到了梦想开始的地方,并且重新开始学习3D,最新的DirectX11.1。回过头看看这些很有趣,DirectX8的主要设计做了哪些改变,导致了今天几乎难以理解的Direct3D API。还记得3级流水线的DirectX2,旋转,灯光和光栅化分为三个基本阶段?这里是一个现代的 DirectX 11.1 三维管线图。

是的,它增加到了9-13级,其中包含一些可选项如compute shader。作为一个拥有极其资深的背景并且非常低级别的3D图形编程人员,我不好意思承认我学习 Direct3D 11.1 学得非常的痛苦。Direct3D API变得非常的不可理解和难以学习。我无法想象没有和我一样深厚的3D图形背景的人该如何开始入手学习现代可编程3D渲染管线。这条管线惊人的强大而且难以使用,但是极少数最聪明的人都在从事3D图形。在我赶上现代Direct3D的过程中,我发现我敬畏现代GPU的惊人力量,它们会发展到哪一步,同时震惊、厌恶3D管线已经发展到绝对的混乱。在过去的几年中,Direct3D API已经成为OEM要求的3D特性倾销地。

如果我不是享受着长达十年参与DirectX的回报,毫无疑问,我会酸溜溜的写些什么乱七八糟的我的前辈创建了伟大而优雅的消费型3D图形显示的悠久历史。然而,古怪的是当时间定格到了现在,我必须承认,我不能确认但这毕竟是件坏事。PC游戏市场的停滞,和微软与OEM推动Direct3D API的背后是XBox的成功。大量零散的3D API并不是个大问题,如果和游戏机一样,开发者只需要支持一种硬件配置。早期的DirectX 8.0支持Shader Model 1.0是第一代Xbox的图形API的基础。作为第一代XBox的选择,NVIDIA芯片在PC 3D图形芯片市场拥有了巨大的优势。DirectX 9.0和更先进的Shader Model2.0,是XBox360的基础,微软重新选择了ATI设计3D芯片,AMD这个时候在PC图形市场拥有了巨大优势。从某种意义上说OEM自己绞死了自己。通过成功影响微软和OpenGL标准组织采取高度错综复杂的图形管线,以支持他们所有特性,他们迫使自己去归纳他们的GPU架构,而显卡芯片市场会围绕一种架构合并… 无论微软为它的游戏机选哪个。

最终的结果是,PC游戏的零售市场接近于死亡。这对于开发一个高产值的游戏来说,简直是个太太昂贵,太没有安全感,太不稳定的平台,除了MMOG。微软和OEM的同谋毁掉了众所周知的摇钱树。这对微软来说没什么大不了的,因为微软很高兴通过XBox控制了PC游戏前端业务。

从很早的DirectX视觉的角度来看,我认为这个结果是一个愚蠢且短视的灾难。微软应该保持DirectX团队的纪律,把战略重心放在Direct3D API,他们可以确保没有其他游戏机和XBox同一个时代,通过XBox加强PC游戏市场,而不是无意之中破坏它。虽然祝贺微软开发了首款美国产的成功的游戏机,但是我会计算如果微软保持一个有凝聚力的跨平台战略,从索尼,任天堂和移动平台所能获得的回报。我说这些是从过去的角度来看,因为今天,我不能肯定,我对所以的结果感到不满。

索尼和微软的新一代游戏机已经恢复到PC架构!下一代GPU将是大规模并行,与CPU共享私有缓存的通用处理器。事实上,GPU架构变得如此通用,是因为在DirectX 11中加入了一个称为DirectCompute的新流水线阶段,允许CPU绕过整个Direct3D图形管线直接编程。随着DirectCompute的引入,简单的3D编程以一个意想不到的形式返回。现代GPU已经变得如此强大和灵活,直接采用GPU编程开发3D引擎是一个越来越实用和有吸引力的编程选择。从我的角度来看,我预计在短短数代的时间里,传统的Direct3D和OpenGL API将会消失,新的引擎将会亲睐与采用如Nvidia的CUDA和微软的AMP之类的独立的shader语言来编写更丰富,更多样化的特效。

今天,作为一个3D物理引擎开发者,我从来没有如此兴奋,因为现代GPU编程纯粹而强大,并且相对容易编程,而无需学习错综复杂的Direct3D和OpenGL API的3D管道。如果今天是我负责Direct3D的战略,我会主张抛弃传统的3D管线,快速转向丰富的GPU编程环境。我个人从来没有想过,我早期工作过的Direct3D,在几十年中,促进演变出了一种新的无处不在的处理器,可以支持在1980年我所学到的那种令人难以置信的逼真的光照和物理模型,我从没想过电脑能强大到在我的职业生涯中出现实时渲染模型。

Direct3D API 的遗产:

  • 左手坐标系,我在DirectX2.0做的糟糕决定
  • 伴随Windows 95问世的COM API
  • 各向异性过滤,在Direct3D中发现的Talisman的最后遗迹
  • Shaders, 在DirectX8.0中引入,标志着固定管线的结束和可编程渲染管线的问世
收藏 1 评论

关于作者:浅水清流

程序员 游戏开发 服务器(新浪微博:@浅水清流) 个人主页 · 我的文章

相关文章

可能感兴趣的话题



直接登录
最新评论
跳到底部
返回顶部