无论是通过文字、绘画还是肢体语言,图像一直是传递信息和记录历史的重要手段。视觉反馈的要求是如此重要,以至于如果你看不到某样东西,就很难肯定它的存在。例如,在十七世纪安东尼·范‧列文虎克(Antonie van Leeuwenhoek)发明显微镜并在视觉上发现细菌之前,细菌的存在纯属猜测,但这后来却成为现代科学不可或缺的一部分。
第一批个人电脑于 20 世纪 70 年代中后期开始出现,但当时被视为业余爱好者的发烧级机器。随着 1977 年苹果电脑公司发布 Apple II 和 Commodore International 发布 PET,这种情况发生了一些变化。这些机器普及了家用计算机的概念,但在计算机图形方面并没有太多优势。
到了 20 世纪 80 年代,随着图形用户界面等技术被引入个人计算机市场,这种情况发生了一些变化。在这一时期,第一批专用图形附加卡(graphics add-on cards)也开始出现,特别是 IBM 的 CGA(彩色图形适配器,Color Graphics Adapter),它是 IBM 个人计算机平台上的第一块彩色图形卡,通过标准化一种绘制计算机图形方法为未来的发展铺平了道路,但在图形能力方面并没有提供太多的功能。
1992年,id Software 发行了第一人称射击游戏《德军总部 3D》,这是当时推动硬件实现的一款电脑游戏。虽然《德军总部》不是真正的 3D 游戏,但它定义了未来 3D 电脑游戏的标准。仅仅一年之后,id Software 发行了他们的第一款真正的 3D 游戏《毁灭战士》。这是第一次,玩家可以通过台阶和电梯探索他们的环境,而不用被固定在某个高度。许多游戏模仿了《毁灭战士》的外观和感觉,并被称为「毁灭战士克隆‘Doom-clones’」。《毁灭战士》使用软件渲染器将它的实时图像渲染到屏幕上,就像 90 年代早期的所有其他游戏一样,但这种情况即将改变。
然后你可以通过一个扩展加载机制在程序中加载这些扩展,并检索函数指针,就可以调用这些扩展提供的功能。然而,这种加载机制并没有标准化,因此每个平台都有自己特定的扩展加载函数。这种限制在 Microsoft Windows 平台上最为明显,因为 OpenGL 头文件自 OpenGL 1.1 版以来就没有更新过,即使在最新的 Windows 开发工具包中也是如此。本章稍后将详细介绍这种情况的原因。
1993 年,微软公司的工作站操作系统 Windows NT 进入市场时,基于 UNIX 的工作站已经开始使用 OpenGL。Windows NT 是作为 UNIX 的直接竞争对手发布的,它支持联网(NT 首字母缩写的意思是网络技术)和 32 位硬件。Windows NT 引入了至今仍在使用的功能,如用于创建 Windows 应用程序的 Win32 API。但由于系统中没有 3D 图形库,微软承诺在 Windows NT 中添加对 OpenGL 的支持。
微软公司终于在 1994 年发布的 Windows NT 3.5 中实现了 OpenGL,但实现 OpenGL 的程度仅限于通过实现 SGI 公司当时提供的示例实现来声称其兼容性。该示例实现的目的仅仅是演示如何实现 OpenGL,并为供应商提供参考。不用说,这实现的速度慢得可怕,因为它没有经过优化,并且当时 PC 上几乎不存在图形加速器。事实上,这个性能问题非常明显,以至于微软知识库中有一篇文章 (KB121282) 警告说,使用 NT 3.5 的 OpenGL 屏保程序可能会降低机器的运行速度,因为它会占用计算机 CPU 的大量时间。
DirectX
微软看到了视频游戏市场的商机,于是为 Windows 寻找自己的 3D 图形 API,以怂恿游戏开发人员抛开 DOS(微软的第一个操作系统),纯粹为 Windows 开发游戏。他们的首次尝试是 WinG,它只是将命令传递到底层的 GDI(图形设备接口 Graphics Device Interface)接口,不提供 3D 功能。为此,微软不得不在 1995 年收购了一家名为 RenderMorphics 的公司,该公司生产了一种名为 Reality Lab 的 3D 图形 API。该 API 更名为 Direct3D,并在名为 DirectX 的 SDK(软件开发工具包 Software Development Kit)中发布,其中还捆绑了其他一些游戏开发专用的 API:
DirectDraw 用于快速绘制 2D 图形
DirectInput 用于捕捉摇杆输入
DirectPlay 用于联网和通信
DirectSound 用于声音播放
Direct3D 的最初版本使用起来很不方便,开发人员采用该 API 的速度也很慢。这使得微软在继续支持 OpenGL 的同时,也在努力使 Direct3D 成为具有竞争力的 API。OpenGL 1.1 规范已在 Windows 95 和 Windows NT 4.0 中实施,它带来了急需的性能提升,但这也是微软最后一次更新 OpenGL ,转而采用自己的 API。
「API 大战」的开端
虽然微软一直坚持认为 OpenGL 最适合用于「专业图形」,即工作站上的 CAD(计算机辅助设计 Computer Aided Design),但它已开始在视频游戏中得到应用,而微软正试图通过 DirectX 在 Windows 平台上主导这一行业。OpenGL 最大的突破来自于 id Software 公司颇具影响力的开发人员约翰·卡马克(John Carmack)将其著名的视频游戏《雷神之锤》移植到 Windows 平台上来使用 OpenGL API,并向开发人员展示了使用 OpenGL API 是多么容易。
如果您想了解更多相关信息以及当时的微软文化和亚历克斯·圣·约翰,可以阅读这本很棒的书《帝国的变节者(Renegades of the Empire)》,或者访问他的博客 AlexStJohn.com,在那里他偶尔会谈论他在微软的时光,以及仍在进行的 OpenGL 与 Direct3D 之争。
Direct3D 在 5.0 版本中变得更加实用,该版本从 API 中删除了一些令人不舒服的功能。在这一点上,两种应用程序接口都对用户相当友好,功能集也很相似,但这种现状即将改变。
驱动程序的崩溃
由于 OpenGL 和 Direct3D 在 Windows NT 上处于胶着状态,微软需要一个优势。在 Windows NT 中,OpenGL 驱动程序是通过使用迷你客户端驱动程序(Mini-Client Driver,MCD)实现的,它是硬件和软件之间性能较低的折衷方案,但却是创建驱动程序最简单的解决方案。MCD 允许供应商挑选他们希望在硬件上加速的部分,而其余部分则在提供的软件实现上运行(反之亦然)。微软通过不允许在 Windows 95 上授权使用 MCD,从而有效地将 OpenGL 限制在微软提供的软件实现上,从而获得了他们所需的优势。
2006 年,OpenGL 2.1 作为原始 2.0 规范的一个小增量发布,只带来了少量新功能。雪上加霜的是,微软在发布新的 Windows Vista 操作系统的同时还发布了 Direct3D 10.0,其中包括对 API 的重大修改和许多新功能。硬件开始向新的方向发展,从即时模式、固定功能方法转向更可编程的方向,而这正是 OpenGL 所缺乏的。
这些修订承诺了一个全新的 API,能够与 Direct3D 10 的 API 竞争,就像 Direct3D 10 所做的那样,Mt. Evans 将消除即时模式渲染,只依赖缓冲区和着色器。这次 API 重写是一个伟大的事业,需要几个技术小组(Technical Sub-Groups,TSG),他们专注于自己的 OpenGL 规范的专业领域。
对象模型 TSG (Object Model TSG)就是其中之一,负责处理如何在新的 API 中表示缓冲区和其他类型的对象。拟定的对象模型提出了一种只需调用几个函数就能创建对象的全新方法。最重要的是,通过使用模板(templates),所有类型的对象所使用的方法都将保持一致。这意味着供应商之间将不再存在不符合之处,他们将以五花八门的方式提供他们的对象创建功能。
现在是开始学习 OpenGL 的大好时机,因为视频游戏正被大量移植到 Microsoft Windows 以外的平台上,而在 Windows 以外的平台上获得实时计算机图形的唯一途径就是 OpenGL。例如,《半条命》的开发商 Valve 就使用 OpenGL 作为图形库,将他们的许多热门游戏移植到了苹果 Macintosh 上。
此外,现代智能手机(如 iPhone 和基于 Android 的手机)都使用 OpenGL ES 来实现交互式 3D 图形,这是一种基于嵌入式系统(embedded systems)的 API,与 OpenGL 非常相似。这意味着,您的代码可以在 PC、Mac、游戏机以及各种移动设备上运行。
OpenGL ES 本身催生了另一个名为 WebGL 的 API,这是一个跨浏览器、跨平台兼容的三维图形应用程序接口,适用于网络浏览器。这个库有可能将网络和多用户应用程序提升到一个全新的水平。
下一层是抽象(Abstraction)层,包含 OpenGL 或 Direct3D API 实现。重要的是要区分应用层中的 API 与抽象层中的 OpenGL 和 Direct3D 实现。用 C 语言来说:您可以将应用层视为只包含定义的头文件,而抽象层则是包含实际功能的源文件。抽象层来进行发送至下一层,通过以可用的和标准化格式实现硬件层级的功能。
OpenGL 的设计目标之一是易用性和跨平台兼容性,其抽象层次不允许开发者直接控制硬件细节来充分利用显卡的并行计算等能力。故 OpenGL 的管理者 Khronos Group 由最初的 AMD 开发的 Mantle 而发展出了更加底层的图形 API 标准 Vulkan,在 2015 年将其宣布为下一代的 OpenGL 计划,随着移动平台性能的提升,提供新的统一的行业标准(先前由于移动平台硬件问题,催生 OpenGL ES 的压缩版本)。如老牌游戏开发商 id software 的自研引擎 id tech 6 所开发出的《德军总部 2》以及《DOOM》就有非常良好的 Vulkan 的表现。
微软 Direct3D 12 版本也是同样的思路,更进一步更新为底层 API 来更直接地和底层硬件进行交流,提供优化和充分发挥硬件能力的可能,并随着后续更新,加入了光线追踪(Ray Tracing)的功能。而 Apple 苹果作为软硬件结合的开发商,也发布了自家的图形 API Metal,同样也是一个底层级的图形 API。
使用越底层的图形 API 的游戏或软件并不代表其性能一定好,因为其编码要求更高,如果没有足够丰富的经验和能力,可能还不如使用更高层的 API,就如同样使用了 DX12 的《方舟进化》的表现远不如《战地1》一样。(在游戏主机如 PS4上,也有诸如 GNM 底层 API 和使用 GNMX 高层 API 的区别)。
但电子游戏的开发者并不常直接使用对应的图形 API 进行游戏开发,因为那就需要每开发一个平台都要写一次图形和渲染代码——开发者通常使用游戏引擎作为一个不同平台和图形 API 的中间层来进行开发。
所以当前的游戏引擎如 Unity,就会支持多种图形 API (https://docs.unity3d.com/Manual/GraphicsAPIs.html),具体取决于 API 在特定平台上的可用性。那么如果开发者要在游戏引擎(这样的一个跨平台应用)中写调用底层 GPU 的 shader 代码,那么你需要使用引擎所推荐的着色器语言,如 Unity 中你需要使用 HLSL(High Level Shading Language,是 Direct X 图形 API的语言),以及 Unity 官方的 Shaderlab 框架(底层为 Nvidia 的 Cg 语言)来编写 Shader(或使用 Shader Graph),而后 Unity 会再将其编译为能够调用其他图形 API 的语言。
故纵观计算机图形学到电子游戏渲染的历史,这始终是一个统一与分裂的市场竞争,以及性能与通用性之间的权衡:1. 不同显卡硬件及其显卡驱动需要支持同样的图形 API 的标准来便于软件使用,但最终还是分裂为了多种图形 API。2. 不同的图形 API 标准需要被同样的游戏引擎的图形架构所统一,以便于开发者能够在一个引擎上开发适用于多平台的游戏。3. 但是这个游戏引擎对接各个图形 API 的图形架构的统一模版并不能满足多样的游戏渲染风格的要求,故过去的 Unity 统一的内置(built-in)的渲染管线又再一次需要更加可定制化,开放了可编程渲染管线,Scriptable Render Pipeline,将图形架构变得可以定制修改的,提供一个更灵活的,对应不同图形 API 的可编程的函数,可容许更加底层定制的渲染管线的自定义。
评论区
共 条评论热门最新