14.1 本篇概述

古人有语:以史为鉴,可以知兴替

历史如此,技术亦然。通过研究现代引擎的演变历史,可以更加系统、详细地了解引擎的技术内幕,从而掌握底层原理,挖掘规律,预判技术或行业的未来。恰好这段时间笔者通读了1000多篇各类论文和文献,抽取了其中的数百篇文献,总结归纳成此篇文章,以飨同行。

14.1.1 游戏引擎简介

本节将阐述游戏引擎的定义、功能、模块以及基本框架。

游戏往往有很多共同的功能,将这些功能创建抽象出通用功能的框架,即是游戏引擎(Game Engine)。更准确地说,游戏引擎是一系列模块和接口,使游戏开发团队可以专注于产品游戏内容,而不必关注技术内容。

游戏引擎按照完整性看分为一体式和模块化两种类型。一体式是GameMaker、RPGMaker之类的引擎,模块化的引擎是指UE、Unity之类的引擎。本篇将着重阐述模块化类型的游戏引擎。

游戏引擎是通用游戏所依赖的功能或模块。游戏引擎是一个框架,由一组不同的工具、实用程序和接口构成游戏的各种任务的详细信息。简而言之,游戏引擎可定义为:可扩展的软件,无需重大修改即可用作许多不同游戏的基础。

现代游戏引擎架构的常见模块。

有许多计算机游戏类型,主要有第一人称射击游戏 (FPS)、实时策略 (RTS) 和角色扮演游戏 (RPG)。所有类型都包含单人游戏(其中使用人工智能模拟其他玩家)或多人游戏(其中几个玩家可以通过计算机网络在同一个虚拟世界中互动),或两者兼而有之。而不同的游戏引擎更擅长某些类型的游戏创作。比如Unreal Engine更适合室外的FPS,Unity更适合轻量级的移动端游戏,等等。

大多数现代电脑游戏可以分为三个部分:游戏引擎、游戏逻辑和游戏艺术。游戏引擎是在计算机上运行的主要可执行文件。它提供了一个运行游戏逻辑的环境,以及基本的数学、图形、音频、用户输入和网络功能。游戏逻辑可以采用脚本、虚拟机字节码或库(例如 DLL)的形式。游戏逻辑的任务是控制游戏玩法,并使用引擎适当地展示游戏艺术。游戏艺术包括图片(游戏用语中的纹理)、地图(虚拟世界的布局)、模型(居住在世界上的事物的 3D 表示,例如玩家、武器或花盆)和声音。

游戏和游戏引擎的关系。

游戏、游戏引擎、计算机的抽象分层。

游戏引擎内的常见分层结构和模块。

现代游戏引擎的模块详情。

通过改变游戏逻辑和艺术,可以使用游戏引擎来创建许多不同的计算机游戏。在某些情况下,如果源代码可用(如Quake 2),则可以修改游戏引擎本身。

总之,游戏引擎为游戏创作团队提供游戏开发的方方面面,使得游戏开发者需要更少的编程技能,可以快速、高效地创建出具有专业品质的虚拟内容。游戏引擎的尺寸、模块化和可移植性的增加,以及与之相关的改进工具被认为是从第一款游戏到今天发展的总体趋势。

使用游戏引擎的目的有几个:

  • 灵活性。可以做任何原生 API 让我们做的事情,没有删减功能。
  • 生产率。比原生 API 更易于使用,更少的代码,更少的精神负担。
  • 性能。与手写原生代码类似的CPU帧时间。
  • 简单。保持接口尽可能少而精。



主流商业游戏引擎的部分特性。

利用游戏引擎创作游戏等产品,拥有的好处是:

  • 更少的代码
  • 更高的生产力 = 更少的时间!
  • 可用性(易于使用)
  • 与设计程序的兼容性(集成)
  • 更多工具,更多选择
  • 插件和库
  • 跨平台

当然游戏引擎并非万能,也存在诸多限制,比如:制作与引擎预期不同的类型可能很困难,让引擎做任何意想不到的事情可能很困难,游戏开发者对引擎的弱点会限制游戏的品质和效率。

14.1.2 游戏引擎模块

游戏引擎是游戏或模拟游戏的核心软件,用于描述用于开发游戏的一组代码。在屏幕上看到并在游戏世界或模拟环境中与之交互的一切 均由游戏引擎提供支持。它允许抽象并执行普通游戏的细节或模拟相关的任务(例如渲染、物理、输入),使开发者可以专注于制作他们的游戏的各个方面模拟特性。

典型的游戏引擎组件和类型图。

游戏引擎的设计侧重于灵活性,允许对其功能进行简单扩展,可以很容易地修改以适应受某些因素(如内存等)限制的平台。引擎分为两个不同的部分,称为框架和管理器。框架包含游戏中重复的部分,意味着它们会有多个实例,还包含与主游戏循环的执行有关的项目。管理者是游戏逻辑所依赖的单例。下图说明了组成引擎的不同部分:

游戏引擎最基础的模块必然包含时间更新、场景管理、渲染(图形、绘制)、输入事件等等。

拥有以上基础模块之后,高级一些的游戏引擎,还拥有更多复杂的模块,诸如摄像机、屏幕管理、网络、音频、物理、动画、模型等等。

应用程序维护的屏幕映射表,屏幕可以使用事件或将它们传递到不同的屏幕。

渲染模块是引擎的核心功能,一直以来是游戏引擎的重中之重,也是行业从业人员重点攻克的阵地。一个游戏引擎的成功与否,渲染模块占据非常重要的地位。渲染模块最简单的功能如设置相机、绘制形状、设置形状的材质属性、绘图文本,从而生成标准图形API接口,通过操作系统或(和)驱动程序像GPU发送并执行绘制指令。

高级的游戏引擎往往还有高层的游戏通用模块,如玩家控制、插件体系、编辑器、自动化工具、资产管理等等。游戏引擎还担负着跨平台、图形API、硬件差异等抽象和处理工作。现代游戏引擎往往包含着更加复杂、多样、全面的模块和工具链,可将它们分为低层级、中层级、高层级模块。具体如下:

  • 低层级模块

    • 数据结构

      • 数组、链表、树、图、哈希表
    • 算法
      • 排序、动态规划、并行循环
    • 数学
      • 向量、矩阵、四元数
      • 几何计算
      • 随机数
      • 其它数学模块
    • 内存管理
      • 游戏引擎通常使用自定义内存管理
      • 必须避免碎片化
      • 分层内存管理
      • 寻址
      • 垃圾回收
      • 显卡内存管理
    • 资源和文件IO
      • 快速加载
      • 寻址
      • 解析
      • 文件格式
      • XML
      • 压缩
      • 资源打包
    • 输入设备
      • 控制板、操纵杆
      • 键盘、鼠标
      • 特殊硬件(触觉,6-DOF)
      • 力反馈
      • 麦克风
      • 相机
      • 配置
      • 按钮映射
      • 校准
    • UI
      • 基础控件
      • 事件管理
      • UI动画
    • 性能监测
      • 时间是关键资源
      • 各种硬件,每个都有自己的时序和性能特征:CPU、图形、音频、IO
      • 存在许多复杂的分析器
      • 游戏内预算和警告游戏预算和警告
      • 游戏内绘图 游戏绘图
      • 用于全面分析的调试工具
  • 中层级模块

    • 渲染

      • 详见图形子系统
    • 音频
      • 3D 空间化:平移、多普勒、杜比环绕、HRTF(与头部相关的传递函数)
      • 管理声音优先级(声音)
      • 混响,效果
      • MIDI
      • 音乐
      • 动态音乐
      • 流式传输 CD / DVD(多个流)
      • 语音
    • 文本
    • 碰撞检测
    • 物理学
    • 脚本
    • 联网
    • 角色动画
    • 电影播放
  • 高层级系统

    • 场景管理
    • 用户控制
    • 相机
    • AI(人工智能)
    • 游戏逻辑
    • 游戏流程
    • 灯光、视觉效果
    • 平视显示器
    • 前端(用户界面)
  • 图形子系统

    • 渲染

      • 在硬件之上分层
      • 常用 API:OpenGL、Direct3D、Vulkan、Metal
      • 渲染多边形网格(显示列表)
      • 照明
        • 漫反射、镜面反射、AO、GI、IBL、PBR
      • 图形状态
      • 矩阵和视图转换
      • 着色器
      • 特殊材质
        • 皮肤、头发、眼球、二次元
    • 场景管理
      • 场景图
      • 加速结构:KD树、四叉树、八叉树、Portal、BVH等
      • 贴花
      • AI
      • 碰撞
    • 剔除
    • LOD
    • 地形渲染
    • 角色换肤
    • 粒子引擎
    • 效果(天空、水、植被、雾)
  • 工具

    • 代码开发工具

      • 编译器(Visual C++、SN Systems、CodeWarrior、GNU)
      • 调试器
      • 探查器
      • 编辑
      • 修订控制(CVS、SourceSafe、SVN)
      • 集成开发环境 (IDE)
      • C++、汇编、脚本语言
      • 图形语言:像素和顶点着色器……
      • 设计分析工具
      • 文件、标准
    • 中间件

      • 渲染:RenderWare、NDL、Intrinsic、OGRE、OpenSceneGraph
      • 物理引擎:ODE、Havok、PhysX、牛顿
      • 数学引擎
      • XNA、Bink、FMOD、ScaleForm
    • 艺术制作工具

      • 3D 建模和动画(Maya、3D Studio)
      • 导出导出模块模块
      • 资产管理(AlienBrain)
      • 绘画(2D 和 3D)(Photoshop、Z-Brush、DeepPaint)
      • 扫描(2D、3D)
      • 动作捕捉
      • 游戏内工具和编辑器
    • 音频工具

      • 录音
      • 作曲(ProTools)
      • 音效(原因)
      • 空间音频配置工具
      • 游戏内工具
    • 游戏设计工具

      • 游戏内工具
      • 关卡布局
      • 原型制作工具(Director、Flash)
      • 设计工具
      • 图形用户界面工具
        • CEGUI、NGUI、UMG

      开源渲染引擎OGRE集成的CEGUI编辑器一览。

对于交互,游戏或模拟中的交互游戏或模拟中的交互非常重要,是整体用户满意度的最重要因素。每个游戏/模拟都有自己的要求,具体取决于类型、支持的控件、交互的响应时间、交互响应的真实程度等。每个应用程序的目标群体在很大程度上定义了交互选项。

只要有可能,用户自定义和修改交互参数的能力是必不可少的、至关重要的,例如鼠标移动速度、鼠标移动速度反转、上下轴反转、多上下轴、多模态控制模态控制等。常见的一种游戏执行流程包含处理窗口消息、调度器执行、分发更改、检测执行状态,如下图所示:

通用的场景和物体的关系如下图所示,每个系统包含一个或多个场景,每个场景包含一个或多个物体:

游戏引擎通常由工具套件和运行时组件组成,下图显示了构成典型3D游戏引擎的所有主要运行时组件。像所有软件系统一样,游戏引擎是分层构建的,通常上层依赖于下层,反之则不然。当较低层依赖较高层时,会引发循环依赖。在任何软件系统中都应避免依赖循环,因为它们会导致系统之间出现不良耦合,使软件无法测试,并抑制代码重用,对于游戏引擎这样的大型系统尤其如此。

游戏引擎中常见模块的细节和特性。通常采用了分层架构,上层依赖下层,反之不然,否则会引起不良的循环依赖。(图摘自《Game Engine Architecture Third Edition》)

游戏引擎的工具套件存在多种创作方式,部分工具可能是独立的软件,部分工具可能构建在运行时引擎使用的一些较低层之上,还有一些工具可能内置在游戏本身中。例如,基于Quake和Unreal的游戏都拥有一个游戏内控制台,允许开发人员在运行游戏时输入调试和配置命令。



上:独立的工具架构;下:共享于游戏之间的框架式工具。

游戏引擎分层示意图。

平台相关的模块。

核心系统相关的模块。

游戏逻辑相关的模块。

游戏引擎中涉及的各类管理器如下图所示:

如何识别游戏引擎的通用部分?看待这个问题的一种方法是专注于将游戏引擎定义为除内容之外的所有内容,每个游戏引擎的通用部分将包括:

  • 主循环(或替代结构)
  • 处理游戏数据文件或链接到用代码编写的游戏数据的模块
  • 处理游戏逻辑的模块,可以但不是必须由数据文件指定
  • 从播放器获取输入的模块
  • 将输出呈现给播放器的模块
  • 辅助模块,例如网络和菜单处理

14.1.3 游戏引擎列表

目前市面上的游戏引擎数量达到惊人的上百个,有些是当前风靡全球的商业引擎,有些是研制出很多3A级游戏的游戏公司内部引擎,有些是用于学习或研究的开源渲染器,有些则是曾经流行但现在已经淡出历史舞台的引擎。下面将阐述部分常见的游戏引擎。

14.1.3.1 Unreal Engine

虚幻引擎(Unreal Engine,UE)是一款集图形渲染和开发套件的商业引擎,在历经数十年的发展和沉淀,于百擎大战中脱颖而出,成为引领实时渲染领域的全球性的通用商业引擎,广泛应用于游戏、设计、仿真、影视、教育、医学等行业。它出自游戏公司Epic Games,最初由Tim Sweeney负责,从上世纪90年代中期就开始,已经经历了20多年,历经数个大版本迭代。

Unreal Engine 2是一个完整的游戏开发框架,针对当今主流PC、微软的Xbox游戏机和索尼的PlayStation 2。Unreal Engine 2X是Epic自制游戏Unreal Championship 2: The Liandri Conflict中令人瞠目结舌的视觉效果背后的高度优化引擎。

Unreal Engine 3是一个完整的游戏开发框架,适用于下一代游戏机和配备DirectX9的PC,提供顶级游戏开发者所需的大量核心技术、内容创建工具和支持基础设施。虽然Unreal Engine 3对Mod制作者开放程度很高,但使用UE3发布和销售游戏的能力仅限于引擎许可。在2009年11月,Epic发布了一个免费版本的UE3 SDK,称为Unreal Development Kit (UDK),可供公众使用。

Unreal Engine 4相比之前版本有了很大的改进,使之成为一款风靡全球的游戏开发引擎。虚幻引擎是一套完整的构建游戏、模拟和可视化的集成工具。其特性包含但不限于实时逼真渲染、可视化脚本、实时光线追踪、完善的游戏框架、专业动画和过场、完善的工具链等等。

Unreal Engine 5于2020年5月13日发布预览视频,支持所有现有系统,包括次时代游戏主机PlayStation 5和Xbox Series X/S。该引擎的研发工作在发布前约两年就已开始,且在2021年中期发布了Early Access版本的源码,并计划于2022年全面推出。Unreal Engine 5采用了两大核心技术:

  • Nanite:允许将高细节摄影源材料导入游戏的先进技术,可用于处理游戏场景中复杂的几何体;
  • Lumen:用于解决游戏的全局光照细节,并且不依赖于硬件的光线追踪。





从上到下依次是Unreal Engine 1、Unreal Engine 3、Unreal Engine 5的编辑器界面。

早期的Unreal的基于光照图的光照效果。

Unreal Engine作为行业顶级的通用商业游戏引擎,被游戏行业广泛使用,并研制出了许多知名、画面精良的游戏。





用Unreal Engine研发出的游戏截图。从上到下依次是UE3的Batman: Arkham City、UE4的最终幻想7重制版、UE5的黑神话悟空。

有了UE5的Nanite、Lumen等技术的加持,使得实时互动游戏朝着影视级的画质发展,Epic官方放出的黑客帝国演示demo便是最好的例证(下图)。

Epic用UE5研制的黑客帝国互动Demo截图,画质直逼电影,让人无法区分游戏和电影的界限。

除了游戏行业,虚幻引擎还被广泛应用于影视、仿真、设计、广电、科学可视化等领域,并逐渐完善了相配套的工具链和生态社区。

UE用于演习和模拟器中以进行培训。

14.1.3.2 Unity

Unity由Unity Technologies公司研发维护,是一个具有功能强大的编辑器的跨平台游戏引擎,也是最受欢迎的商业引擎之一。在项目中,开发人员可以控制向移动设备、Web浏览器、桌面和控制台的交付。它的功能非常丰富,使用Javascript或C#编写脚本,存在大型社区支持,非常适合跨平台开发。

Unity的第一个版本 (1.0.0)于2005年6月发布,目标是为业余游戏开发者创建一个价格合理的游戏引擎,并为业余游戏开发者提供专业工具,同时“使游戏开发民主化”行业。这三者的灵感来自Apple的Final Cut Pro产品的简单工作流程、简单的资产管道和拖放界面。最初发布时,Unity仅适用于Mac OS X,开发人员只能将他们的作品部署到少数平台。当前版本可以支持Windows 和 Mac OS X等至少十几个目标平台。

Unity早期版本(版本 0.2)的屏幕截图。

早期Unity游戏Gooball截图(2005)。

14.1.3.3 CryEngine

CryEngine系列引擎由德国游戏开发商Crytek设计的游戏引擎,已被用在CryTek的所有游戏中。初始版本在孤岛惊魂中使用,并继续更新以支持他们的游戏的新控制台和硬件。

CryEngine自2004年发布了1代引擎,到目前的版本V,经历了20多年的发展迭代了数个大版本。Ubisoft维护了一个内部的、经过大量修改的原始孤岛惊魂的CryEngine版本,称为Dunia引擎,用于他们后来的孤岛惊魂系列迭代。

CryEngine和其孪生引擎的发展历程。

CryEngine完整的家族树及游戏列表。

CryEngine 1最早于2004年和Far Cry的技术演示一同发布,支持Shader Model 3.0、HDR照明及其它图形特性。游戏代表作有孤岛惊魂、永恒之塔等。

CryEngine的场景和地形编辑器(2004)。

CryEngine的动态光照效果(2004)。

CryEngine的水体、船、人物相互交互的渲染效果和编辑器(2004)。

Far Cry游戏截图。

CryEngine 2于2007年发布,支持HDR照明、实时环境贴图、体积云、动态水体(水面和水下)、景深、运动模糊、动态软阴影、动捕脸部动画、次表面散射、可互动和破坏的环境、可交互植被、绳索物理等特性。代表作有Crysis、Crysis Warhead等。



Crysis游戏截图。

CryEngine 3在2009年发布,相比上一代引擎,引擎支持 DirectX 9、10 和11的开发,新增了许多先进的图形、物理和动画技术以及许多游戏增强功能,比如:实时间接照明的级联光传播体积、软粒子、多核并发、延迟光照、自然光和动态软阴影、雾效果(体积、分层和视距)、SSAO、全能着色器、人眼适应、HDR照明、运动模糊、DOF、次表面散射、高质量水体、动态体积光束和光轴效果、流环境、多核物理引擎、交互和破坏环境、高速纹理渲染等等。代表作有孤岛危机 2等。

CryEngine3的渲染效果。

CryEngine3研制的射击游戏Nexuiz。

CryEngine (3.6–4)于2013年发布,Crytek将CryEngine(从版本 3.6.0 开始)更名为“CryEngine”,并宣布下一个CryEngine将不会以版本号进行宣传,原因是声称这个新引擎与以前的CryEngine版本几乎没有相似之处。

CryEngine渲染出的大片森林。

CryEngine V(5)在2016年3月发布,CryEngine 5.4在2017年9月发布,添加Vulkan API渲染器作为测试版、物理集成和其它功能,包括新的C#模板、资产系统更新和新的抗锯齿技术。在渲染方面,CryEngine V支持以下特性:

  • 区域光源
  • 基于物理的渲染(PBR)
  • 曲面细分
  • 高效的抗锯齿
  • 实时局部反射
  • 基于体素的全局光照(SVOGI)
  • 屏幕空间方向遮挡(SSDO)
  • 基于图形的光照(IBL)
  • 体积雾阴影
  • 支持DirectX 12
  • 实时动态水体焦散
  • 3D HDR镜头光晕
  • 运动模糊和景深
  • 实时植被
  • 逐物体阴影图。
  • HDR胶片色调映射
  • 粒子特效系统
  • 平行视差映射

CryEngine 5.3编辑器。

CryEngine V沙盒编辑器。

CryEngine V的渲染效果图。

14.1.3.4 Doom / Quake / ID Tech

Quake家族引擎用于创建许多游戏,拥有延伸到荣誉勋章等现代游戏的血统,并且Quake和Quake II引擎源代码免费提供。

在2004前后,Quake 3使用标准的FPS游戏控制系统:鼠标外观和键盘,四处移动鼠标会改变玩家的视线方向,鼠标按钮通常用于向前行走和射击,键盘上的各种按键用于蹲伏、跳跃、后退、扫射和切换武器,可以通过称为键绑定的过程将键重新映射到不同的游戏内功能。Quake 3是一款面向网络的游戏,使用客户端-服务器(CS)通信模型。

Doom、Quake、Unreal等引擎有个共同特点,那就是擅长FPS类型的游戏。下面是详细的FPS游戏及引擎的发展历程图:

其中ID Tech 3支持摒弃了软光栅渲染,需要一个兼容OpenGL的图形加速器运行。引擎的图形概念紧密围绕“着色器”(如今的材质)系统,其中许多表面的外观在文本文件中定义,称为“着色器脚本”。此外还支持基于样条的曲面、曲线顶点动画、基于子模型的动画分离、体积雾、镜像、入口、动态阴影和基于波形的顶点扰动。

14.1.3.5 OGRE

OGRE是一款开源的较为成熟的多平台3D图形引擎,支持OpenGL和DirectX渲染,在LGPL许可下用C和C++编写。 它具有基于OO的设计,并支持可加载的代码模块。它还提供了分层场景图、基本物理函数,并内置了2D GUI系统,支持常用小部件和TrueType字体。在2000年时代,它拥有庞大而活跃的开发人员和用户支持社区。 然而,它不是游戏引擎,只处理图形渲染,故而不支持网络或音频,需要引入第三方库。

用ORGE制作的游戏代表作有Runic Games的火炬之光(Torchlight),Torchlight是角色扮演游戏,类似暗黑破坏神的风格和玩法,于2010 年游戏开发者选择奖最佳处女作奖,可通过数字分发在Windows和Mac上使用。

用ORGE研发的单机暗黑类游戏Torchlight的游戏截图。

Torchlight刚发布之时,笔者恰好入职国内某一线游戏公司,被Torchlight炫酷的画面、技能效果和别具一格的玩法深深吸引,那时还没有996,每天一下班就有大把时光沉迷于探索它的暗黑魔法世界。

在2000年时代,国内涌现了很多游戏公司和团队基于ORGE做魔改和二次开发的自研引擎,其中最为成功的案例便是畅游的天龙八部,它是一款改编自金庸古风武侠小说的网络游戏,曾经风靡一时,至今尚在运营。基于OGRE二次开发的引擎或开源库有很多,其中就包含Ogre Golf。后期的ORGE发展的功能有:可扩展框架、多平台、场景管理器、资源管理器、材质、网格、动画、渲染器、特效、着色器、插件等。

14.1.3.6 Gamebryo

Gamebryo由Emergent Game Technologies研发维护,是一款跨平台的3D游戏引擎,游戏代表作有Fallout 3 (Bethesda)、Civilization Revolution (Firaxis)、Warhammer Online (EA Mythic)等。

Gamebryo引擎以前称为NetImmerse。NetImmerse的开发以几个设计目标为指导,其中最重要的是速度,导致研发者在整个引擎中使用了简单的技术,并大量基于场景图数据结构,允许多种性能增强技术,例如剔除对玩家来说是不可见的游戏对象。

其它设计目标是提供与标准图形和音频接口的兼容性,并提供高级编程接口。引擎研发者声称目标已经实现,并分别指出创建引擎的一个发现是“高级编程接口不需要牺牲性能”。引擎提供高级接口很重要,允许开发人员降低开发成本,并且需要针对引擎进行优化不同类型的游戏。

Gamebryo Lightspeed有着较广泛的游戏作品,提供快速的应用程序扩展框架,另外解耦的架构设计使得游戏团队可以方便地扩展。Gamebryo支持处理声音、图形、物理和多人游戏的各种技术和游戏玩法,它的视觉保真度高,曾被用于制作具有广阔景观的游戏以及复杂的面部细节。此外,它还被用于开发美国政府和军队项目,以及消防和手术模拟。

14.1.3.7 BigWorld

BigWorld(也称为 Wargaming Sydney)是一家澳大利亚公司,由John De Margheriti于2002年成立,该公司开发和许可用于创建大型多人在线游戏 (MMO) 和虚拟世界的中间件开发工具套件。它是第一家为MMO市场开发此类中间件平台的公司。2007年,BigWorld被英国的Develop杂志公认为行业领导者。2012年8月7日,Wargaming以4500万美元收购了BigWorld中间件公司。

BigWorld Technology提供了游戏开发者构建MMO和在线游戏所需的底层软件架构。3D客户端技术专为Windows PC和浏览器构建,可通过网络API在 iOS、Xbox 360和PlayStation 3上使用。 后端服务器解决方案在Linux下实现,具有Python API脚本环境。该工具套件包括内容创建工具、服务器监控工具和支持。BigWorld Technology还集成了各种第三方插件,例如Umbra(遮挡剔除)、Scaleform(用户界面创建)、Speedtree(树叶)和 Vivox(VOIP)。

游戏代表作主要有:World of Tanks系列、天下系列等。

14.1.3.8 Torque3D

早期的Torque3D引擎有几个版本,具体描述如下:

  • Torque Game Engine 1.0:以及 TGE 1.5 的所有功能,它具有 atlas 地形生成编辑器、Torque GFX 图形层、自定义纹理材料、现代场景图和批处理渲染引擎。
  • Torque Game Engine 1.4:这个旧版本的 Torque 仍然具有 3D 工具集、地形引擎、网络引擎和其它功能。基于用于部落 2(Tribes 2)的技术。
  • Torque Game Engine 1.5:1.4.2 的重大升级,具有集成的 Torque 照明套件、ShowTool Pro、附加艺术资产等等。

是2010年之前的一款较流行的游戏引擎,后逐渐衰落,淡出人们的视野。

Torque引擎河流编辑器。

Torque地形编辑器。

Torque引擎的渲染效果。

14.1.3.9 Source Engine

Source Engine是由Valve Software开发的屡获殊荣的3D游戏引擎,最初在1994年被发行出来,被认为是市场上最先进的游戏引擎之一,支持诸如使用Havok引擎的逼真模拟物理、DirectX 9.0支持(包括高动态范围照明、骨骼动画、声音系统和许多其它功能)等功能。它是成功的知名游戏《半条命 2》所依赖的引擎。

源引擎附带可用于构建游戏模组的Source SDK,该SDK对半条命2游戏的所有者免费提供,并提供了对Valve自己用来创建半条命2系列游戏、失败之日源、反恐精英源和即将推出的游戏(包括传送门和军团要塞 2)的工具的访问权限。它也被包括Ritual the creators在内的许多独立开发者使用。

2010前后的Source引擎应用了快速、可靠和灵活的技术,使用以下许多功能呈现计算或渲染密集型游戏:

  • Direct3D(在Windows 95及更高版本、Xbox 和 Xbox 360 上渲染)。
  • OpenGL(在Mac OS X和PS3上渲染)。
  • HDR(高动态范围),HDR 仅在《半条命》的《失落海岸》中引入,而没有在《半条命 2》单人游戏中引入。
  • 具有自动生成唇形同步功能的面部动画系统。
  • 想要修改游戏的人的源代码。
  • 混合骨骼动画系统。
  • 一个模型查看器,用于查看您的角色在不同着色器中的样子。
  • 放置凹凸贴图、纹理等的材质系统。

Source引擎的架构和特性。

使用 Source引擎的Vindictus游戏截图。

14.1.3.10 Frostbite

Frostbite是EA Digital Illusions CE(DICE)开发的一款内部游戏引擎,专为在Windows、PS系列 、Xbox 系列上的跨平台使用而设计X/S系列。该游戏引擎最初用于战地游戏系列,但后来扩展到其它第一人称射击视频游戏和各种其它类型。Frostbite一直是由Electronic Arts发行的游戏所独有的,迄今为止已经发布了3个大版本,其代表作有战地系列、FIFA系列、极品飞车系列、植物大战僵尸系列、星际大战系列等等游戏。





用Frostbite研制的部分游戏截图。从上到下依次是:Need for Speed Heat、Battlefield 2042、Star Wars: Squadrons。

Frostbite虽然是DICE的内部引擎,不对外发行和授权,但因为Frostbite的研发成员活跃于Siggraph、GDC等国际技术峰会,常在峰会上分享最新的渲染技术和研究成果,而享誉盛名于游戏行业。Frostbite公开分享的技术文章列表可参见:EA Tech Blog

14.1.3.11 Anvil

Ubisoft Anvil(直到2009年称为Scimitar,直到2020年称为AnvilNext)是由Ubisoft Montreal创建并用于2007年游戏刺客信条的游戏引擎,包含Scimitar、Anvil、AnvilNext、AnvilNext2.0、Ubisoft Anvil等分支。引擎用于Microsoft Windows、Nintendo Switch、PlayStation 3、PlayStation 4、PlayStation 5、PlayStation Vita、Wii U、Xbox 360、Xbox One、Xbox Series X/S 和 Stadia等平台。专为主机游戏刺客信条打造,后来被用于刺客信条系列、汤姆克兰西的幽灵行动等游戏中。

Ubisoft Anvil图标。

Anvil引擎使用Autodesk的HumanIK中间件在运行时正确定位角色的手和脚以进行攀爬和推动动画。添加的功能包括完整的昼夜循环、增强的绘制距离、与孤岛惊魂 2 相同的植被技术、改进的照明、反射和特殊效果、新的布料系统以及新的AI和NPC导航系统。

AnvilNext增加了对新天气系统的支持,该系统允许特定的天气设置以及在刺客信条IV中看到的自动循环模式。其次,渲染器被重写以提高效率并支持额外的后处理技术,最多可以实时渲染3000个不可播放的角色。最后,AnvilNext 添加了来自Far Cry 4的技术,以支持更加动态的沙盒环境和新的水技术,游戏世界可能会随着时间的推移而变化,具体取决于玩家的行动和进展。更重要的是,从刺客信条Unity 开始的AnvilNext能够以灵活和自动的方式生成结构,同时遵循特定的设计规则和模板,从而减少艺术家和设计师创建错综复杂的城市环境所需的时间和人力。AnvilNext还为不可玩角色提供了改进的AI。

渲染方面,该引擎支持预烘焙的全局照明、反射映射、体积雾、动态天气和动态树叶等等,还有基于物理的渲染 (PBR) ,使材质、对象和表面能够更逼真地查看和反应照明、阴影和阴影。此外,通过添加体积技术,全局照明系统现在更加逼真,以物理为导向的对象反应更加逼真,并且布料在主角、环境和其他角色上的表现更加逼真。世界现在支持更大的陆地、更多的物体、更大的建筑物、无需加载屏幕即可访问的建筑物内部,以及许多其他增强视觉保真度、沉浸感和游戏玩法的附加功能。

代表作有刺客信条系列、For Honor、Tom Clancy's Rainbow系列等等。

Assassin's Creed Valhalla的打斗画面截图。

14.1.3.12 Destiny Engine

Destiny引擎是游戏公司Bungie研发的游戏引擎,用于开发自家的Destiny系列游戏。

2013年,《命运》的大部分基础工作已经完成,包括传说、游戏引擎以及许多环境和任务。

Destiny1代游戏采用了一种新的游戏引擎,称为Tiger Engine,它基于大多数Halo游戏所使用的引擎,允许全局光照和实时动态光照同时运行。此外,Bungie的目标是Destiny将在Xbox One和PlayStation 4上以1080p原生渲染图形。Bungie的“漏斗”技术创新是Halo配对系统的支柱,允许更好的玩家配对,以便在合作或竞争的多人模式中创造更自然的体验。但是,Bungie的开发人员批评新引擎不适合游戏的在线性质,引擎的资源密集型特性使得即使是对地图的微小更改也需要通宵渲染和编译过程,新地图和任务的开发是“艰苦的”。

此外,Destiny的多线程并行技术运用得炉火纯青,并引入到场景渲染的各个阶段。

Destiny引擎的场景渲染并行化图例。

Destiny 2游戏截图。

14.1.3.13 RE Engine

RE引擎(全称Reach for the Moon Engine)是由Capcom公司创建的视频游戏引擎。最初是为《生化危机 7:生化危机》设计的,后来被用于该公司的各种游戏,例如Devil May Cry 5和Monster Hunter Rise。该引擎是Capcom之前的引擎MT Framework的继承者。

RE引擎对MT框架进行了各种改进,包括新的抗锯齿和体积照明功能。该引擎还允许开发人员使用摄影测量来创建更高质量的资产,包括比其前身改进的VR支持,使其能够达到避免眩晕所需的高帧率,支持使动画更快的工具,例如模块化装配、运动匹配、程序动画和运动重定向,还具有各种新的物理模拟选项,允许更逼真的碎片。

代表作包含生化危机系列、怪物猎人、鬼与妖精的复活等。

Resident Evil Village游戏场景截图。

14.1.3.14 RedEngine

RedEngine由CD Projekt开发和维护,主要针对3A级主机游戏的研发,虽然它的名字鲜有人知,但其研发的游戏却是鼎鼎有名,游戏代表作有巫师系统、赛博朋克2077等。

赛博朋克2077游戏截图。

14.1.3.15 RAGE

RAGE全称Rockstar Advanced Game Engine,是由RAGE Technology Group开发的专有游戏引擎,RAGE Technology Group是 Rockstar Games的Rockstar San Diego工作室的一个部门。自2006年第一款游戏Rockstar Games Presents Table Tennis面向Xbox 360和Wii发布以来,Rockstar Games的内部工作室一直在使用该引擎为游戏机和电脑开发先进的开放世界游戏。

早期的RAGE特性有角色动画引擎、物理引擎、处理大型流媒体世界的能力、复杂的 AI 安排、天气效果、快速的网络代码和多种游戏风格,支持DirectX 11和个人计算机的立体3D渲染,以及更强大的绘制距离、纹理过滤以及改进的阴影映射和曲面细分质量。

随着2018年Red Dead Redemption 2的发布,RAGE将进一步完善,支持基于物理的渲染、体积云和雾值、预先计算的全局照明以及Windows版本中的Vulkan渲染器,还可以创建先进的 AI 以及增强的游戏物理和动画,HDR渲染以及深度学习超级采样 (DLSS) 的支持。

游戏代表作有荒野大镖客(Red Dead Redemption)系列、侠盗猎车手(Grand Theft Auto)系列等。

Red Dead Redemption 2游戏截图。

14.1.3.16 PhyreEngine

PhyreEngine是Sony的一款仅许可免费使用的游戏引擎,兼容PlayStation系列平台、 Windows(OpenGL、DirectX 11)、Android和iOS。

PhyreEngine以可安装包的形式独家分发给Sony被许可人,其中包括完整的源代码和Windows工具,根据其自己的灵活使用许可提供,允许任何PlayStation游戏开发商、发行商或工具和中间件公司部分或完全基于创建软件在任何平台上的PhyreEngine上。该引擎使用针对 PS3单元宽带引擎的协同处理器单元 (SPU) 优化的复杂并行处理技术,但可以轻松移植到其它多核架构。

除了低级PS3 LibGCM库之外,PhyreEngine还支持OpenGL和Direct3D,提供功能齐全的“游戏模板”作为源代码,包括对Havok 、PhysX 、Bullet等物理引擎的支持。

PhyreEngine已被多家游戏工作室采用,并已用 200多个已发布的游戏中。游戏代表作有最终幻想系列、英雄传说系列等。

14.1.3.17 Irrlicht

Irrlicht引擎可以使用 OpenGL、DirectX 或软件进行渲染,可以在在 Windows 和 Linux 上运行。技术上,Irrlicht使用了分层场景图进行场景管理,并具有基本的 2D GUI功能。

Irrlicht比同期的其它引擎要小巧一些,只有一个主要开发人员,但是在当时有一个庞大的爱好者支持社区。 它还提供基本的物理例程,但缺少任何网络功能。并且,Irrlicht以图形质量和渲染速度比其它软件差而闻名,被更容易开发所抵消,通常被视为理想的初学者引擎。





Irrlicht引擎渲染画面截图。

14.1.3.18 XNA

Microsoft的XNA Game Studio是一个易于使用且高度可访问的游戏开发平台,旨在鼓励玩家创建自己的游戏并与在线游戏社区分享。

XNA基于C#和公共语言运行时 (CLR)。主要的开发环境是Visual Studio或其免费对应物Visual Studio Express,其源代码和游戏资产等所有内容都在Visual Studio中进行管理。借助XNA,开发人员可以为PC、 Xbox 360控制台创建游戏。通过以基本为零的成本提供出色的工具,微软出色地为普通人打开了创造新游戏的闸门。

XNA研发的游戏Barotrauma游戏截图(2019)。

14.1.3.19 其它引擎

在2004前后,FPS 类型中,有三个主要的游戏引擎系列,每个系列都由不同的开发者组成:id Software的Doom 3和Quake 3引擎、Valve Software的Half Life和Half Life 2引擎和Unreal Tournament (UT)和 Epic Games的 Unreal Tournament 2004 (UT2004) 引擎。

毁灭战士3、半条命2和UT2004代表了每个开发者的最新一代,并且是当时可用的最佳游戏引擎。Quake 3、UT和Half Life是上一代引擎。应该注意的是,Half Life引擎是基于Quake 和 Quake 2引擎的。

所有这些引擎都功能齐全,并且基于这些引擎中的每一个都存在一个或多个完整的游戏,与上面的大多数开源引擎形成鲜明对比,后者提供了更多基本功能。开源引擎通常需要与其它库和工具包结合才能创建可玩的游戏,Quake 3值得特别提及,和其它引擎不同,可以被开发人员进行大量修改。 另一个应该提到的引擎是GarageGames的Torque。它是一种廉价的商用引擎。

此外,还有Cocos2d系列、Panda 3D、OpenSceneGraph、Delta3D、Blender Game Engine、GameMaker、Godot、bgfx、Unigine、Delta3D等等引擎或渲染器。

Blender Game Engine编辑器和渲染效果图。

下面是另外一些引擎的特点描述:

下表是部分游戏引擎的说明:

名称 公司 许可 代表作 备注
4A Engine 4A Games 专用 Metro 2033, Metro: Last Light, Metro Exodus
A-Frame (VR) Google MIT - 开源Entity组件系统WebVR框架
Alamo Petroglyph Games 专用 星际大战
Anvil Ubisoft 专用 刺客信条、汤姆·克兰西的彩虹六号
BigWorld BigWorld Technology 专用 坦克世界、天下
Blender Game Engine Blender Studio GPL-2.0+ Yo Frankie!, Sintel The Game 2D/3D游戏引擎封装在3D模型中,集成子弹物理库
Cocos2d 多个 MIT Geometry Dash 国内是Cocos2d-x/3d引擎
Creation Engine Bethesda Game Studios 专用 上古卷轴、辐射
CryEngine CryTek 专用 孤岛危机、孤岛惊魂
Dark Engine Glass Studio 专用 Thief: The Dark Project、System Shock 2、 Thief II: The Metal Age 高级 AI 和声音功能(完全控制声音传播)
Decima Guerrilla Games 专用 死亡搁浅、地平线零黎明、杀戮地带:暗影坠落、直到黎明、直到黎明:鲜血狂潮
Dunia Engine Ubisoft 专用 全境封锁 基于CryEngine
EGO Codemasters 专用 F1系列 主要用于赛车游戏
Essence Engine Relic Entertainment 专用 帝国时代4、战锤、英雄连3
Fox Engine Konami 专用 实况足球
Frostbite Ubisoft DICE 专用 战地、FIFA、星球大战
Gamebryo Gamebase 专用 攻壳机动队:独立情结、冒险岛2
GameMaker Studio YoYo Games 专用 警察故事、死亡诡计
Glacier IOI 专用 杀手系列、自由战士、迷你忍者、凯恩与林奇系列
Godot Argentina MIT 残酷小队、硬编码、转储王国、Keen in Keen Dreams 3.0+通过模块和GDNative添加了C#脚本和其它语言、PBR和全局照明。
HeroEngine Simutronics 专用 星球大战:旧共和国
id Tech id Software 专用 Doom、Quake、愤怒、德军总部:新秩序、德军总部:旧血、内心的邪恶 从Doom和Quake发展而来,早期版本部分开源
Irrlicht Nikolaus Gebhardt zlib Minetest
IW Engine Infinity Ward 专用 使命召唤系列 最初基于id Tech 3构建
Jade Ubisoft 专用 Rayman Mini、Space Junkies、Tom Clancy's Ghost Recon Breakpoint
Kinetica Sony 专用 战神
MonoGame / XNA Microsoft Microsoft Public 幕府将军的骷髅、泰拉瑞亚、堡垒、塔楼坠落、晶体管、非斯、公理边缘
Odyssey Engine BioWare 专用 星球大战:旧共和国骑士团,星球大战:旧共和国骑士团II:西斯领主
OGRE - MIT Torchlight, Kenshi
OGRE-Next - MIT - OGRE的下一代引擎
Panda3D - BSD 卡通城在线,加勒比海盗在线
PhyreEngine Sony 专用、免费 英雄传说:步入遐想、天空:光之孩子
Real Virtuality Bohemia GPL-2.0+ ARMA 2、ARMA 3、DayZ
RedEngine CD Projekt 专用 巫师 2:刺客之王、巫师 3:狂猎、赛博朋克 2077
RAGE RAGE Tech 专用 荒野大镖客1和2、侠盗猎车手
RPG Maker ASCII 专用 女巫之家、Escaped Chasm
SAGE Westwood Studios、 EA 专用 指环王系列、命令与征服系列
ShiVa ShiVa Technologies 专用 波斯王子2:阴影与火焰
Silent Storm engine Nival Interactive 专用 寂静风暴、守夜人、锤子和镰刀、日间守夜人 用于回合制战术游戏
Source Valve 专用 半条命2、反恐精英:来源、Left 4 Dead、传送门、军团要塞2、Dota 2、实验室、神器、半条命:Alyx 第一款使用Source 2的游戏Dota 2是从原始 Source引擎移植过来的,The Lab的一个迷你游戏Robot Repair使用Source 2引擎,而其余七个使用Unity的引擎。
TOSHI Blue Tongue 专用 侏罗纪公园:创世纪行动、尼克卡通联盟、·里维拉历险记、漫威超级英雄小队
Torque3D GarageGames MIT Marble Blast Gold、Tribes 2、Blockland 包括多人网络代码、无缝室内外渲染引擎、骨骼动画、拖放 GUI 创建、内置世界编辑器、类 C 脚本语言
UbiArt Framework Ubisoft Montpellier 专用 雷曼起源、雷曼传奇、光之子、勇敢的心:大战
Unigine Unigine 专用 Dual Universe 专注于大型开放场景:64位精度坐标,支持地理坐标,圆形地球模型,主要用于企业和专业模拟器。
Unity Unity Technologies 专用 天刀、原神、最终幻想、王者荣耀、炉石传说
Unreal Engine Epic Games 专用 和平精英、黑神话悟空、蝙蝠侠、最终幻想重制版 UE4删除了UnrealScript

以上只是其中部分引擎,更详细的参见:List of game engines

14.1.4 游戏引擎简史

电脑游戏已经走过了漫长的道路,从1962年的太空大战到在21世纪最大的媒体中占据一席之地,在总收入方面甚至超过了电影行业。从技术上讲,计算机游戏就像任何其它计算机程序一样,由源代码模块组成。有人定义的游戏引擎指的是与游戏内容分离的模块部分:行为或环境。就像汽车的引擎一样,游戏引擎是游戏的技术核心,游戏的内容就建立在它之上。

关于游戏引擎的确切含义存在一些混淆,游戏引擎被定义为“不直接指定游戏行为(游戏逻辑)或游戏环境(关卡数据)的模拟代码模块的集合”。在引擎的模块中,游戏世界的输入处理、输出(3D、2D 和声音)以及通用物理和动力学。游戏引擎作为对游戏实际内容没有影响的模块,包括输入、音频、图形、动态和事件循环。

设计和开发软件组件是一个成本高昂且耗时的过程,因此游戏开发人员通常在经济上更好地投资于现成的引擎而不是开发自己的引擎,重复使用优质组件也提高了整个产品的整体质量。构建新软件不可避免地会导致“重新发明轮子”,与以前创建的软件相比,代码重复估计高达85%。

在实践中,游戏引擎通常会根据特定游戏的内容风格进行调整,但会损害引擎在不同风格游戏中的重用性。大多数引擎都是为在特定平台上运行特定游戏而设计的,引擎越通用,在特定平台上运行特定游戏的优化程度就越低。更一般地说,构建可重用的软件组件所花费的精力是构建一次性组件的三倍。因此,虽然重用现有游戏引擎具有相当的价值,但每个人都构建自己的可重用引擎或每个游戏引擎都可重用(或者甚至与游戏的其它部分分开)则没有意义。

在上个世纪80年代之前,由于没有游戏引擎,每个游戏都需要重复造轮子,必须针对所使用的特定硬件进行构建,多个发行平台意味着从头开始重写游戏,对游戏开发团队而言,意味着多倍的又重复的工作。

到了80年代,游戏引擎的前身概念出现,以Pinball Construction Set (Bill Budge)为例,售出超过300000份。

Pinball Construction Set游戏画面(1982)。

Pinball Construction Set定义了一种新型的产品:游戏构建系统,包含IDE、命令行界面、精灵编辑器、模型编辑器、地图/场景编辑器等。

到了1990年代,游戏创建系统实际上就是游戏引擎,游戏引擎的术语正式开始出现,由id Software引入,在Wolfenstein 3D(德军总部 3D)的FPS游戏中展现,引擎名为Fast 3D Engine(实际是2.5D)。

早期游戏引擎经历的3个阶段。

id Software随后发布了正式版游戏引擎Doom和Quake系列。Doom引擎的特性包含纹理映射、非正交墙、光源衰减/光源、可变高度的地板和天花板、环境动画和变形、调色板转换、多玩家等。Quake引擎则支持降低3D复杂性以提高速度、预先计算光照和阴影(光照贴图)、分割地图以提高速度、快速渲染、渲染顺序、硬件3D加速、网络游戏等。

初代Quake引擎的最低系统要求和渲染画面。

在随后的1999,Quake引擎在GPL下发布,由此衍生了庞大的Quake引擎家族。(下图)

id Tech引擎家族树。

Stardock游戏引擎发展历程。

从上世纪90年代到如今,游戏引擎已经经历了30多年的发展,势头迅猛,衍生出一代又一代的经典技术和架构,涌现许多通用的引擎和内部引擎,由此帮助了数量众多的游戏开发团队和公司,创作出了许许多多耳熟能详的游戏作品。

上世纪90年代,游戏引擎还处于混沌期和萌芽期,很多游戏开发团队尚没有使用游戏引擎,只对基础和通用的模块进行部分抽象,在各个项目之间进行复制。这种模式是处于低级的复用,更别谈扩展性、维护性和易用性了。

没有游戏引擎的助力,加之游戏技术和硬件的限制,当时的游戏画面极其粗糙,颜色位深有限,像素严重不足,颗粒感十足。(下图)





上:Saboteur II(1989);中:Xenon 2(1990);下:Prince of Persia 2(1995)。

到了上世纪90年代,以ID公司的Doom和Quake系列引擎和Epic公司的Unreal引擎开始面世,诸多通用的功能模块、亮眼的游戏画面和较为易用的编辑器,使得它们成为当时的主流游戏引擎。(下图)



上世纪90年代的Doom、Quake、Unreal引擎的游戏画面。

早期的游戏引擎编辑器界面。

2000年前后,Quake和Unreal引擎发展到了第三代,部分游戏引擎发展的描述和时间线如下图所示:

关于Doom、Quake、Unreal引擎更详细的时间线如下图所示:

引擎核心模块愈来愈多,尤其引擎渲染、粒子等效果的完善,使得游戏也愈发炫酷。

2008年发行的用UE3研制的音乐类游戏Nurien Mstar Online。

在随后的短短数年间,各类游戏引擎如雨后春笋般涌现,除了老牌的Quake、Unreal、CryEngine外,还诞生了Torque、BigWorld、Gamebro、Irrlicht、OGRE等等引擎,触发了百擎大战的序幕。这股风潮也吹到了国内,几乎每个游戏公司都有引擎团队,做自研引擎工作或对国外引擎进行二次改造。那时候的许多引擎程序员都有个梦想,那就是拥有个人的游戏引擎。

随着游戏品质要求的提高,对引擎技术、工具链的要求越来越高,许多技术底子本就不深厚的团队逐渐无法满足需求,败下阵来,从历史的舞台褪去。逐渐形成了少数技术雄厚的老牌游戏引擎鼎立的架势,引擎的天下被他们分而治之。

其中后起之秀就有Unity引擎,它以小巧、跨平台、简单易上手著称,被广泛用于移动游戏和网页游戏。Unity以Entity-Component的场景对象结构为核心,简化了场景节点管理,提升了可扩展性,避免以往的以继承为主的类型爆发式增长。后续在Entity-Component的基础上,发展成了ECS(Entity-Component-System)。

Unity的GameObject-Component模式。

Unreal的继承和Entity、Component相结合的模式。

游戏对象以各种方式相互关联,可以绘制描述这些关系的图表,任何这样的图表都可以作为事件的分发渠道。

和ECS伴随着的是从面向对象设计(OOD)向面向数据设计(DOD)的转变,以便明确区分实例、组件、系统并各司其职,将适用于具有某些组件集的实体的代码形成系统,结合Structure-of-Arrays (SoA)的数据布局,利用线性遍历提升内存访问效率,提升缓存命中率,从而提升效率。

OOD和DOD在内存布局上的区别。

SOA内存布局示意图。

随着功能的增加,技术的发展,现代引擎由工具套件和运行时组件组成,在引擎架构上,将硬件扩展到高级应用程序,基于的分层设计,避免循环依赖以最大化重用和可测试性。

游戏引擎架构图。采用了分层模式,包含了游戏相关的子系统、核心系统、资源管理器、渲染引擎、前端、平台抽象、低级组件、第三方库等分层。

以上跟渲染强相关的分层或跟模块是渲染引擎,它分为低级渲染器、场景图管理、视觉效果、前端等层级。

低级渲染器专注于尽可能快速和丰富地渲染图元,不考虑可见性,图形设备相关接口(访问和枚举图形设备、初始化 GD、设置缓冲等),还有、几何图元的表示、相机接口的抽象、材质系统、动态照明系统、文字和字体等。

低级渲染器的模块详情。

场景图限制提交渲染的图元数量,使用截锥体剔除——移除可见屏幕之外的东西,采用空间细分结构(BSP、四叉树、八叉树、kd-tree)。

场景图的模块详情。

场景图的一个案例。

视觉效果包含粒子系统、贴花系统、光照映射、动态阴影、全屏后期效果等模块。

前端包含HUD、菜单、用于字符操作的 GUI、用于过场动画的全动态视频等。

另外,DCC工具和资产的数据流如下图所示:

面对大型游戏,涉及的资产非常庞大,需要一种方法来存储和管理大量数据,一些公司使用关系数据库(MySQL 或甲骨文),一些公司使用版本控制软件(SVN、Perforce 或 GIT),还有一些人使用定制软件,例如顽皮狗使用一个名为Builder的自定义GUI。

独立和集成两种方式的工具架构图。

另外,还涉及基于网页的工具,用于各种用途(资产管理、调度、错误管理),更容易构建,通常比独立应用程序更容易构建,无需强制重新安装即可轻松更新,如果它只需要显示表格数据并有表格 - 使用网页界面。

Integrating Architecture Soar Workshop探讨了如何集成不同引擎、技术栈研究的架构设计。(下两图)



网络技术的发展给游戏引擎的网络模块增强了动力,使得大型多人在线游戏蓬勃发展并取得瞩目的成绩,最典型的例子便是暴雪的魔兽世界,开启了日常跑团副本的先锋。(下图)

图片显示了魔兽世界游戏中的一个大型活动现场,有成千上万的玩家在同一个地方实时地交流和互动。

时间来到2010年前后,移动设备智能化的趋势明显,以iOS的移动端系统和iPhone 4的硬件设备在全世界范围内广泛追捧,自此拉开了移动设备智能化的历史进程。游戏作为智能移动设备的首要功能,自然成为国内外游戏厂商的目标,因而他们都在转型到移动游戏开发。

2008年到2012年的游戏份额图例,其中移动端的游戏占比逐年增加。

2017年移动端游戏的占比已达29%。

Unity作为小而精的代表,敏锐地察觉到移动端的商机,于是避开PC上的已然存在的众多老牌游戏引擎的竞争,集中精力转向移动端的研发之路。

2012年的Unity已经支持移动端的开发。

与此同时,由于单核CPU摩尔定律逐渐接近天花板,CPU厂商往多核的方向发展,因此,游戏引擎也在顺应多核并行化发展。

CPU的核心、频率、性能、晶体管从1970到2014年的趋势图。

并发引擎架构的层级。从上到下划分为引擎系统层、内核层、框架层、操作系统层。

并发引擎的循环步骤示意图。

另外,由于移动设备的特性,对性能异常敏感,并行化也是其趋势之一。The Benefits of Multiple CPU Cores in Mobile Devices阐述了在移动端多核CPU的技术,如何在SMU、ARM架构的CPU上协同地和NV的Tegra 2的GPU完成并行化任务,以达到性能最大化并且省电。

双核ARM Cortex A9 MPcore架构。

双核CPU的电压和频率扩展优势。

多核化的设备使得主流游戏引擎能够充分利用多线程的优势,完成很多并行化的任务。下图是其中部分游戏引擎的线程数量:

下图是游戏Dungeon Defender使用了NVIDIA Tegra处理器的两个内核:

同期的Frostbite是另一个使用基于作业的并行性的游戏引擎示例,它能够使用底层硬件平台提供的尽可能多的线程。引擎在GPU上执行主要的Game和Render任务,并将其它系统相关的工作划分为作业。每个作业通常包含15K到200K行C++代码,平均作业大小约为25K行代码。 大多数这些工作是独立的,而一些具有多线程游戏使用两个 CPU 内核相互依赖。游戏的每一帧通常包含200到300个作业,并且引擎将作业分配给所有可用的硬件内核。

Frostbite引擎上的任务级并行性。

上图中的每种颜色都代表Frostbite启动的一个作业,该数据是使用Frostbite Timing View软件在具有四核CPU和两个处于AFR模式的GPU的PC系统上收集的,从图中很容易看出,游戏引擎有效地使用了所有可用的内核进行任务处理。因此,这些游戏引擎将能够有效利用 NVIDIA Tegra的两个CPU内核和ULP GeForce GPU内核,并提供无与伦比的游戏机风格游戏体验,这种并行技术成功地应用在了Battlefield: Bad Company等游戏上。

启用了多核之后,在Quake引擎上的帧率可以提升1.6倍以上,而游戏Dungeon Defender的帧率提升2倍以上。(下图)



在渲染技术方面,以暴雪的Naty Hoffman、迪斯尼的Brent Burly、Epic Games的Brian Karis等行业科研人员率先在实时渲染尝试PBR技术的应用。

PBR涉及的部分演讲如下:

Naty HoffmanPhysically Based Shading Models for Film and Game Production

Brent BurlyPhysically Based Shading at Disney

Brian KarisReal Shading in Unreal Engine 4

以下是主流引擎支持PBR的时间表:

  • Unreal Engine 4:《Real Shading in Unreal Engine 4》,SIGGRAPH 2013
  • Unity 5:《Physically Based Shading in Unity》,GDC 2014
  • Frostbite(寒霜): 《Moving Frostbite to PBR》,SIGGRAPH 2014
  • Cry Engine 3.6:《Physically Based Shading in Cry Engine》,2015

随后PBR技术逐渐在主流渲染引擎中普及开来,成为实时互动游戏的标配技术和标准工作流。





从上到下:Naty Hoffman科普PBR技术、迪斯尼原则的PBR参数化预览、UE4的PBR效果。

2015年前后,基于现代化的新生代图形API横空出世,典型的代表是Vulkan和DirectX 12。它们的共同特点是将诸多控制权由驱动程序转移到了应用程序层。具体地说,新的图形AP的特点有:

  • 允许多线程命令缓冲区记录。

  • 减少运行时/驱动程序的工作量。

  • 减少运行时验证。

  • 将工作移至初始化/加载时间(例如管道设置)。

  • 更明确地控制硬件。

  • 减少便利功能。

  • 精确地管理内存。

    DX12的资源管理图例。

这样的转变使得游戏引擎有了更多的控制图形API的机会,以便做极致的渲染优化。并行化命令录制、多线程渲染、内存精确管理和基于整帧优化的渲染图(亦被称为帧图)等技术就此诞生。

Frostbite引擎采用帧图方式实现的延迟渲染的顺序和依赖图。

UE作为老牌的追求渲染质量的游戏引擎,在2018年改变了原来的市场格局,在Steam平台上显示,25%左右的游戏采用它来制作,一举超过了Unity,稳坐榜首。(下图)

在Steam上发布的游戏中使用的游戏引擎(数据来自2018-12-20)。

此外,现代图形API以及GPU渲染管线的进步,使得某些以往受限的渲染技术得到蓬勃发展,例如GPU驱动的渲染管线、基于Cluster的渲染、光线追踪及实时全局光照等等。

GPU驱动的渲染管线概览。

光栅化、计算着色器和光线追踪的混合渲染管线。

基于面元(surfel)全局光照的面元可视化。

有了以上技术的强力支撑,使得当前的游戏达到了影视级的画质,最突出的便是利用UE5的Nanite和Lumen等技术研制出的《黑客帝国》Demo以及游戏科学的《黑神话:悟空》。

近些年,图形API标准已经支持人工智能,Nvidia率先在RTX系列GPU芯片上集成了Tensor Core,由此基于深度学习的人工智能技术也大量地引入到图形渲染和游戏引擎当中,例如光线追踪降噪、DLSS、智能化NPC的AI、风格化渲染等等。

DLSS关闭(左)和开启(右)的对比图,帧率提升了71%。

DLSS在部分3A游戏上的加速比例图。

此外,除了传统的PC、主机等实时渲染平台,移动端、XR、网页端和云端渲染等分支也得到了较大的发展。

2018年主流商业引擎支持VR、移动等平台的表格。

2020年的移动端市场份额,达到770亿美元,在新冠的阴霾下依然逆势同比增长13.3%。

其中由于XR设备比普通移动设备对带宽、电量、性能更加敏感,于是诞生了注视点渲染、多视图渲染、可变着色率、插值、预测、时间扭曲、多线程等等优化技术。

用于优化VR等渲染的MultiView对比图。上:未采用MultiView模式的渲染,两个眼睛各自提交绘制指令;中:基础MultiView模式,复用提交指令,在GPU层复制多一份Command List;下:高级MultiView模式,可以复用DC、Command List、几何信息。

Arm在UE上使用4-视图的多视图进行注视点渲染,可以减少65%的渲染工作量。

14.1.5 内容概要

本篇将时间作为主线,划分成几个部分:

  • 萌芽期(1999之前)
  • 成长期(2000~2009)
  • 开花期(2010~2015)
  • 结果期(2016~2021)

内容主要围绕着游戏引擎的架构和渲染部分,但不仅仅限于此,还包含相关的模块或笔者认为值得关注的内容。

14.2 萌芽期(1999之前)

游戏引擎始于1990年代中期,尤其是与第一人称射击游戏 (FPS) 等3D游戏相关,也就是Doom(下图)和Quake游戏的流行,其他开发人员不用从头开始工作,而是授权软件的核心部分并设计自己的图形、角色、武器和关卡。

左:Doom游戏截图;右:Doom 3游戏截图。

尽管游戏引擎的术语在1990年代才首次使用,但在1980年代也有一些较早的系统也被认为是游戏引擎,例如Sierra的AGI和SCI系统、LucasArts的SCUMM系统和Incentive Software的Freescape引擎。然而,与大多数现代游戏引擎不同,这些游戏引擎从未用于任何第三方产品。后来的游戏,例如Quake III Arena和Epic Games的1998 Unreal,在设计时就考虑到了这种方法,引擎和内容是分开开发的。至少,可重用引擎使开发游戏续集变得更快、更容易,这在竞争激烈的计算机游戏行业中是一个宝贵的优势。

左:Unreal的Skaarj角色截图;右:Unreal 3的Berserker角色截图。

在早期的PC开发游戏,最简单的游戏循环如下所示(想必学过windows开发的同学肯定接触过):

// 开始消息循环
MSG kMsg;
while ( TRUE )
{
// 优先处理消息
if ( PeekMessage(&kMsg,(HWND)0,0,0,PM_REMOVE) )
{
if ( kMsg.message == WM_QUIT )
break;
HACCEL hAccel = (HACCEL)0;
if ( !TranslateAccelerator(hWnd,hAccel,&kMsg) )
{
TranslateMessage(&kMsg);
DispatchMessage(&kMsg);
}
}
else // 空闲循环
{
// 绘制调用
Draw();
}
}

上面的Draw函数绘制过程(OpenGL为例)的最简单的实现如下:

void Draw()
{
// 清理缓冲区颜色
glClear(GL_COLOR_BUFFER_BIT);
// 设置渲染状态
glDisable(GL_CULL_FACE);
// 设置模型到世界的变换
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glMultMatrixf(gs_afMatrix);
// 绘制三角形
glBegin(GL_POLYGON);
glColor3f(gs_afColor0[0],gs_afColor0[1],gs_afColor0[2]);
glVertex3f(gs_afVertex0[0],gs_afVertex0[1],gs_afVertex0[2]);
glColor3f(gs_afColor1[0],gs_afColor1[1],gs_afColor1[2]);
glVertex3f(gs_afVertex1[0],gs_afVertex1[1],gs_afVertex1[2]);
glColor3f(gs_afColor2[0],gs_afColor2[1],gs_afColor2[2]);
glVertex3f(gs_afVertex2[0],gs_afVertex2[1],gs_afVertex2[2]);
glEnd();
// 恢复之前的变换
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// 交换缓冲区,将后台缓冲区复制到前台缓冲区
SwapBuffers(gs_hWindowDC);
}

当然,以上只能对应简单案例,例如绘制Hello World这样的场景。对于复杂的场景,需要引入更多技术、加入更多调用,从而形成更复杂的游戏主循环。下图是3D Game Engine Architecture提及的一种场景节点的交互图:

空间类、节点类、几何类和渲染类之间的相互关系。

在当时,场景的节点组织结构以继承为主(尚未出现Entity-Component和ECS),物体的数据结构以Entity为节点:

早期游戏场景的Entity节点结构图例。

早期游戏场景的Entity节点结构图例2。

随着时间迁移,各种新兴的渲染技术和硬件的进步(如纹理映射、抗锯齿、像素和顶点着色、改进的阴影生成、增加的内存带宽、增加的填充率……),使得游戏的环境更加逼真,而且它们也愈加复杂、绚丽。(下图)

id公司研发的游戏随时代演变的画面。从左上到右下依次是Wolfenstein 3D(1991)、DOOM(1994)、Quake(1996)、Quake 3(1999)、DOOM 3(2004),肉眼可见的画质进步。

随着物体、光源的增加,渲染技术越来越复杂,使得渲染状态需要执行复杂的管理,以便提升效率。下图是3D Game Engine Architecture阐述的渲染状态更新技术:

更新渲染状态的情况。通过树状结构,游戏引擎可以方便地收集依赖关系和渲染状态。

在光照上,此时期的游戏常以多纹理获得光照效果。(下图)

多重纹理以获得暗图和光图。左上:木质的主要纹理,右上:与主要纹理结合的次要纹理,左下:一张暗图,下中:使用硬叠加的光照图,右下:使用软叠加的光照图。

CryEngine1为太阳阴影提供了阴影贴图和每个对象的投影阴影。为了提升性能,预先计算了植被阴影,但内存限制为非常模糊的纹理。对于高端硬件配置,CryEngine1为植被添加了阴影贴图,但将它们与预先计算的解决方案结合起来依然有不少问题。

CryEngine1将模板阴影用于点光源,以获得更简单、更有效的解决方案。CPU蒙皮允许在CPU上提取阴影轮廓,然后在GPU渲染模板阴影。很显然,当想要渲染更详细的对象时,这种技术会成为一个问题,因为它依赖于CPU蒙皮,需要额外的CPU计算、上传到GPU、边缘数据结构的额外内存,并且几乎没有可预测的性能特征。由于缺少对alpha混合或经过测试的阴影投射器的支持,因此该技术甚至无法用于棕榈树(下图)。

Far Cry游戏截图,使用了软预计算阴影与实时阴影相结合的方案。

在此阶段,已经诞生网格的LOD技术,下图展示了同一个网格的两个LOD的外观和三角形数量:

地形渲染也初见雏形,拥有了较大的视野、LOD过渡、特殊的纹理过滤(如双线性、各向异性)和雾效:

在此阶段,也已经兴起了Billboard(公告板)技术,用于粒子特效及部分远景物体的模拟。

14.2.1 图形API

14.2.1.1 DirectX

DirectX是微软定制的图形API标准,是当今非常流行的主流图形API标准之一,是一组应用程序编程接口 (API),专用于Microsoft平台上处理与多媒体相关的任务,尤其是游戏编程和视频。最初,这些API的名称都以“Direct”开头,如Direct3D、DirectDraw、DirectMusic、DirectPlay、DirectSound等。DirectX这个名称是作为所有这些API的缩写词(X代表特定的API名称)而创造的,并很快成为该集合的名称。

随版本变化的DirectX图标。

微软最早于1995年发布DirectX 1.0版本,随后几乎保持一年一发布的速度。截至1999年,已经发展到了DirectX 7.0。1996年微软发布了DirectX 2和3两个大版本。另外,因特殊原因,DirectX 4从未被公开发布。(下图)

DirectX 3.0的图形特性包含硬件级加速的位图、表面、线条绘图,支持高位图的颜色深度,拥有一个支持MMX的光栅化器。

DirectX 3.0研制的游戏截图。

DirectX 5.0的图形特性包含新增直接将多边形信息直接传递到硬件的DrawPrimitive接口、程序化网格和增强的动画、与排序无关的抗锯齿、基于范围的雾、各向异性纹理过滤、无缓冲隐藏表面消除等。

graph TD
A(Stipple Test) --> B(Z-Buffer)
B --> C(Fetch Texels from single texture. Filter to final texture color.)
C --> D(Texture Blend)
D --> E(Add Specular)
E --> F(Apply Fog)
F --> G(Alpha Blend)
G --> H(Write to Frame Buffer)

DirectX 5.0的固定渲染管线。

DirectX 5.0研制的游戏截图。

DirectX 6.0的图形特性包含更快的性能、用于更好照明和转换的更好的几何引擎、为具有硬件3D加速器的用户提供更快的软件光栅化器,以及对多纹理、凹凸贴图、纹理压缩、模板缓冲区和W缓冲区等。

DirectX 6.0的立方体环境贴图效果。

DirectX 6.0研制的游戏截图。

DirectX 7.0的图形特性包含多纹理(组合两个或多个纹理贴图,如光照贴图)、立方体环境贴图、硬件变换和光照、顶点混合(GPU骨骼蒙皮)等。

DirectX 7的光照图效果。

DirectX 7的立方体环境图效果。

DirectX 7的顶点混合(GPU骨骼蒙皮)效果。图左没有顶点混合,图右启用了顶点混合。

14.2.1.2 OpenGL

OpenGL(开放图形库)是独立于平台的2D和3D可视化规范标准,由Silicon Graphics Inc于1992年推出,ARB(架构审查委员会)联盟负责其开发,会员为各大软硬件厂商(ATI、NVIDIA、英特尔、微软等),2006年由Khronos Group联合接手其开发。OpenGL的一个特点是开发缓慢,因为规范化是一个缓慢的过程,极大地阻碍了图形密集型应用程序的开发者。

在1999年及之前,OpenGL发布的版本和特性如下表所示:

版本 时间 特性
1.0 1992年6月 一组基准功能、支持扩展
1.1 1997年3月 纹理对象、顶点数组
1.2 1998年3月 3D纹理、BGRA和打包像素格式、成像子集
1.2.1 1998年10月 增加ARB扩展的概念

OpenGL存在开发扩展套件GLFW,是一个开源的多平台库,用于桌面上的OpenGL、OpenGL ES和Vulkan开发,提供了一个简单的API,用于创建窗口、上下文和表面,接收输入和事件。它具有如下特点:

  • 支持 OpenGL、OpenGL ES、Vulkan 和相关选项、标志和扩展。
  • 通过轮询或回调支持键盘、鼠标、游戏手柄、时间和窗口事件输入。
  • 支持多窗口、多显示器、高 DPI 和伽马映射。
  • 易于集成到现有应用程序中。
    • 只需两个函数调用即可为您提供窗口和 OpenGL 上下文。
    • 附带教程、指南和参考文档、示例和测试程序。
    • 许多不同语言的社区维护绑定。
  • 用 C 语言编写。
    • 原生支持 Windows、OS X 和许多类 Unix 系统(Linux、FreeBSD)。
  • 具有 OSI 认证许可证的开放源代码,允许商业使用。
    • 访问本机对象和平台特定功能的编译时选项。

除了GLFW,还有GLEW、GLUT、gl3w、glad等等扩展库,具体列表见:OpenGL Related toolkits and APIs

14.2.2 硬件架构

1995年,Nvidia发布了NV1的显卡,晶体管达到100万个,特性是16位色彩、最近点过滤,性能达到每秒处理5万个三角形、100万个像素和

1996年,3dfx公司发布了 Voodoo 1代GPU,是第一张3D加速卡(4MB RAM,50 Mhz),仅支持3D可视化,需要一个额外的2D视频卡,在市场上获得巨大的成功。它的理念是将2D变换由快速的2D显卡执行,例如流行的Matrox视频卡,而3D变换由Voodoo卡执行,Voodoo的硬件能够进行比软件渲染更快的计算。

一个典型的Voodoo Graphics PCI扩展卡包括一个DAC、一个帧缓冲处理器和一个纹理映射单元,以及4 MB的EDO DRAM,DRAM和图形处理器以50MHz运行。它只提供3D加速,因此计算机还需要传统的视频控制器来处理传统的2D软件。

搭载Voodoo 1芯片的显卡外观。

同年,NVIDIA和ATI(后被AMD收购)开始了自己的GPU系列,例如Nvidia的(NV1、RIVA 128、Geforce 256),ATI的3D Rage、Rage Pro、Rage 128等。显卡一经面世,立刻大受欢迎,主要原因是合理的价格、广泛的销售渠道和被游戏和操作系统(主要是Windows)支持。

在随后的短短两年内,3dfx公司陆续推出了Voodoo Rush、Voodoo 2等芯片。Voodoo Rush将2D和3D统一在了一块,无需额外的2D处理器。但由于2D和3D的带宽争用,Voodoo Rush性能并不佳。

此外,Rush芯片组并不直接存在于PCI总线上,而是必须通过2D芯片的链接寄存器进行编程。与Voodoo Graphics一样,没有中断机制,因此驱动程序必须轮询Rush以确定命令是否完成;通过2D组件的间接性在这里增加了显著的开销,并倾向于备份PCI接口上的流量。与Voodoo Graphics相比,典型的性能损失约为10%,在窗口模式下甚至更糟。Voodoo Rush卡的销售非常糟糕,并且这些卡在一年内就停产了。

1998年3月,Voodoo 2面世,架构上和1代类似,但硬件上增加了第二个纹理单元,支持一次绘制两个纹理。Voodoo 2需要三个芯片和一个单独的VGA显卡,性能上比同期其它产品都要好,但也存在一些限制。Voodoo2引入了扫描线交错 (SLI),其中两块Voodoo2板连接在一起,每块画出屏幕扫描线的一半,SLI将支持的最大分辨率提高到 1024×768。由于使用三个独立显卡(两个 Voodoo 2 SLI加上通用2D图形适配器)的高成本和不便,Voodoo2 SLI方案对总市场份额的影响很小,在财务上并不成功。

几个月后,带有集成2D/3D芯片组的Nvidia RIVA TNT(下图)发布,对Voodoo2的霸主地位构成轻微挑战。RIVA TNT添加了第二个像素管线,使得渲染速度翻倍,并且使用了更快的内存。与Voodoo2不同,它还增加了对32位(真彩色)像素格式、3D 模式下的24位深度缓冲区、8位模板缓冲区和对1024×1024像素纹理的支持。此外,改进的mipmapping和纹理过滤技术,包括新添加的对三线性过滤的支持,与TNT的前身相比显著提高了质量,TNT还增加了对高达16MiB SDR SDRAM的支持。与RIVA 128一样,RIVA TNT是单芯片解决方案。

Nvidia RIVA TNT芯片外观。

1999年,Nvidia的GeForce 256(NV10)发布,特点是固定管线,支持DirectX7.0,硬件及坐标变换和光照,支持立方体环境图、凹凸贴图、2x各项异性过滤、三线性过滤、DXT纹理压缩等功能。

在90年代,显卡的部件和布局尚显简单,最明显的是散热装置,98年的显卡只需要少许散热片,到了03年,便需要风扇来散热(下图)。

显卡除了物理部件的改进,处理速度和带宽也在飙升,呈现或超越摩尔定律曲线。下图是NVidia的从TNT(1998)到GeforceFX 6800(2004)每秒处理三角形数的曲线图:

图形API标准和GPU硬件的发展,使得游戏引擎如虎添翼,在此时代有了较大的发挥空间。

14.2.3 引擎发展

人类历史上第一款电脑游戏通常认为是1962年的Spacewar,游戏中有两艘玩家控制的宇宙飞船在原始2D显示器上呈现,尽管更简单的游戏甚至更早之前就存在。早期的电脑游戏由低分辨率屏幕上的简单2D图形组成,这种趋势一直持续到1990年代。

1962年的电脑游戏Spacewar,通常被认为是人类历史上第一款电脑游戏。

运行早期游戏的硬件非常有限,迫使开发人员从系统中获取所有处理能力,例如用汇编语言对游戏进行编程,过去的游戏工程主要是关于低级优化。由于硬件有限,早期计算机游戏的架构非常少,仅由事件循环、状态表和图形例程组成。这些游戏彼此之间几乎没有共享可重用元素,这意味着新游戏通常是从头开始编程的。

在早期的冒险游戏中可以看到一丝早期类似引擎的架构,其中第一个是Colossal Cave Adventure,标志着基于文本的互动小说类型的开始,其中游戏玩法包括阅读设置的文本表示并输入简单的命令与之互动。基于文本的冒险在早期游戏中非常流行,后来,结合图形催生了图形冒险类型的架构,但结构非常简单,仅有状态表形式的游戏逻辑、最小级别数据和一个几乎难以识别的事件管理器。

尽管Adventure的架构很简单,但可以清楚地看到数据驱动设计的元素,这就是典型的游戏引擎:游戏的内容与代码明显分离。原则上甚至可以通过更改数据和不理会代码来创建游戏的修改版本。

Adventure的一些继任者都深受其影响,包括Adventureland(Adventure International,1978 年)、Zork(最初由 MIT 的几个学生于 1977年编写,后来Infocom在1980-1982年作为三款不同的游戏发行)和Mystery House (1980年)。虽然Adventureland的机制与原始Adventure几乎相同,但Zork和Mystery House在冒险游戏的开发中产生了两个分支。Zork和其他Infocom的游戏仍然是纯文本的,但具有极大改进的命令解析器,而Mystery House以基本图形为特色(尽管玩家命令仍以文本形式输入),开创了图形冒险游戏的类型。 尽管如此,Infocom的基于文本的游戏在一段时间内更受欢迎,有行业人士后来评论说,当时有限硬件上的图形处理剥夺了本来可以呈现的游戏深度。

左:Mystery House(1980) 右:The Secret of Monkey Island(1990)。

1980年的太空恐慌(Space Panic)是一个单屏游戏,其中一个角色在一个屏幕上移动,躲避外星人,爬上爬下梯子并在地上挖洞。像Donkey Kong(Nintendo,1981年)这样的游戏增加了额外的功能,比如跳跃的能力。更进一步的发展出现在像《超级马里奥兄弟》(任天堂,1985年)这样的游戏中,它用横向滚动机制取代了单屏机制,并添加了其它功能。

左: Space Panic (1980);右: Super Mario Bros(1985)。

在1980年代中期,有一些小型独立视频游戏工作室,研制小型的平台游戏,平台游戏通常是游戏玩家通过在静态和移动平台和壁架上奔跑和跳跃来导航角色穿过充满敌人的关卡(下图)。此类游戏取得了巨大的成功,让全世界的游戏玩家感到高兴。

Darwin the Monkey游戏截图。

与早期游戏架构的情况一样(冒险类型的游戏除外),关于早期平台架构的文献很少。Blow(2004)提供了一些见解,命名了一个 1990年代的2D游戏的一些模块(流式文件 I/O、声音、主要/杂项、模拟、快速2D图形),同时指出其它类型的游戏可能包含不同的部分,例如获得AI的一部分,可能会失去快速图形节点。

上世纪90年代之前,由于没有成熟的游戏引擎,开发游戏异常困难,并且会重复做很多类似的功能,生产力低下,画面效果颗粒感十足。

在开发游戏过程中,有些游戏工作室对每个游戏都是从新造轮子,这样的后果就是开发一个游戏的时间愈来愈长,并且发现竞争对手研发游戏的时间却在逐渐缩短。而缩短研制游戏周期的工作室正是采用了复用的思维,所有游戏和所有平台游戏共有的许多属性和功能都可以从他们的特定游戏中提取出来,将上一个项目抽象出可重复使用或基础的模块,以便快速用于下一个游戏项目,从而不断地缩短游戏开发时间。

这些工作室不仅发现了最初的一些通用模块,而且几乎认出了所有游戏的可通用组件并将它们集成到单个系统中可以重复使用以制作许多不同的游戏。他们知道游戏内容(图形和声音)可能需要在逐个游戏的基础上创建,由于游戏的外观和声音不同,但他们也意识到存在支持此内容的框架(或基础架构),而这主要是可抽象的。这个框架或系统被称为游戏引擎。

1990年代,具备系统的游戏引擎有两个系列,一个是ID的Doom和Quake系列,另一个是Epic Games的Unreal系列。

许多人认为计算机游戏(尤其是游戏引擎)的转折点是FPS类型的诞生,id Software发行了Wolfenstein 3D (1992) 和Doom (1993),尤其是《毁灭战士》,广泛地流行游戏爱好者中。

Doom的架构也值得关注,Doom的核心软件组件(例如图形渲染、碰撞检测和音频)与游戏内容(例如艺术资产、游戏世界和游戏规则)分离,意味着用户可以在游戏中添加新的关卡、模型和其它资产,有效地创建自己的新游戏。虽然Doom的可编程程度很小,并且从它衍生的游戏继续像原始游戏一样玩,但多家公司授权id Software的Doom引擎来制作他们自己的商业游戏。因此,虽然不是第一个使用数据驱动架构的游戏,但将其流行归因于Doom或许并不牵强。

Doom渲染画面(1993)。

Doom之后是Quake(id Software,1996 年),它继承了Doom的功能,具有真正的3D图形和客户端/服务器架构。Quake还提供了一个真正独立于游戏的游戏引擎,包含一个关卡编辑器和QuakeC(一种可以改变游戏行为的脚本语言)。这是对Doom将数据文件添加到游戏可执行文件的方法的重大改进,并且可编程性极低。Quake的引擎由两部分组成:客户端和服务器,所有输入(键盘、鼠标、操纵杆)和输出(3D 渲染、2D 绘图和声音)都发生在客户端,以及所有实际的游戏玩法,例如玩家运动和物理模拟、AI和QuakeC脚本都在服务器上进行。客户端从玩家那里获取输入并将其发送到服务器,服务器在固定的时间内处理游戏,然后将游戏的状态发送回客户端,客户端为玩家提供视听输出。

Quake III Arena的渲染画面(1999)。

Quake的单人游戏和多人游戏都建立在这种架构之上。在多人游戏中,多个客户端通过网络层与单个服务器(通常在不同的机器上运行)进行通信,而单人游戏使用共享内存缓冲区进行通信,并且每个处理帧都在从客户端获取输入之间拆分,在服务器上处理游戏并在客户端上输出。

除了简化多人游戏中的同步问题(与Doom相比,所有玩家运行自己的游戏模拟并且机器同步进行),客户端-服务器架构强制执行模块化设计,简化调试并保持单人游戏和多人游戏代码相同。

紧随Quake其后的是Quake II(id Software, 1997)和Quake III Arena(id Software, 1999)。随着引擎从Quake 1引擎发展到第三次迭代(Quake 3),它的大小也在随着源代码行数 (SLOC) 和源代码模块的数量增长。随着时间的推移,引擎也变得更有条理,因为第一个版本中的源代码文件只存在于一个文件夹中,而后续版本将源文件组织成一个子文件夹树。在这些版本的引擎中都发现了几个模块:

  • 通用功能模块。
  • 游戏逻辑模块。
  • 服务器特定功能模块。
  • 客户端功能模块。
  • 声音和视频输出模块(在以后的版本中分离)。

研究中分析的所有引擎都是用C编程语言编写的,但是,引擎的第四个版本id Tech 4已经使用C++和面向对象的范式进行了完全重新设计。

聊完1990年代的Quake系列,回过头来再聊聊同期的Unreal引擎。

1991年的ZZT,基本上是一个游戏引擎,其中植入了游戏。该引擎公开了一种小脚本语言,虽然它非常基础,但它是一种完整的脚本语言,可以使用它来编写小游戏脚本。它有一个实时的所见即所得交互式编辑器,用于创建关卡,可以通过几次击键来回切换,添加一个关卡,进行游戏测试并对其进行迭代, 这种交互式工作流程确实是其中的关键。

ZZT的游戏模式和编辑模式。

Turbo Pascal是一个易于使用的编辑器,用于创建代码和编译东西,输入代码的几秒钟后它会被编译,接着就可以运行它。这种编码方式与之前使用的所有东西相比,创建东西的迭代过程体验十分友好。

Turbo Pascal的编辑器。

随后,Epic Games的Tim Sweeney受ZZT和Turbo Pascal的启发,开启了Unreal引擎的研发之旅,Unreal初代版本的很多核心功能和ZZT相似,编辑器则和Turbo Pascal相似。

1998年的Unreal Ed编辑器,使用了Visual Basic。

在随后的若干年,随着技术的演变,Unreal编辑器先后尝试了Visual Base、wxWidget、Slate等UI框架,逐渐形成了如今的编辑器风格和交互方式。后续的Unreal Engine加入了Game Play框架,可以给开发人员快速提供一个可用和可扩展的基础:

Unreal Engine的game play框架图。

除了Quake和Unreal,此时期还存在其它游戏引擎的发展。例如TerraForm3D Plasma Works 3D Engine & USGS Terrain Modeler提到了如何设计一款简洁的引擎(Plasma Works Engine)。Plasma Works Engine的目标是满足双方需求的 3D 引擎设计、基于对象的渲染器、尝试各种特殊效果,以及高质量的图像渲染器、用户驱动的图像处理等。

Plasma Works Engine渲染效果图。

在架构上,以前是单个引擎、相同的建筑基础、开源和专有的问题,现在是两个分离的引擎、不同的架构、OpenGL独有的扩展(GLUT)。

Plasma Works Engine架构图。分为物体和渲染器,它们又引用了各种资源和对象。

Plasma Works Engine初始化和循环流程图。

在数据流上,客户端采用了命令驱动式机制,驱动物体和渲染器,最终渲染出画面像素和光源信息:

Plasma Works Engine的地形建模器涉及不少的包体接口,它们的交互关系如下:

在地形生成和处理上,采用了并行化的分布式架构:

下图是地形编辑器界面:

下图是地形并行化处理的界面:

虽然站在现在的角度,略显初级,但在当时,能够并行化处理是非不易,会遇到IO、纹理带宽、同步、设计模型等诸多方面的问题。

1995年,Architectural Blueprints—The “4+1” View Model of Software Architecture提到了一种4+1视图的软件结构:

  • 逻辑视图(Logical View),说明对象模型。
  • 流程视图(Process View),处理并发的流程和同步问题。
  • 物理视图(Physical View),描述“软件的映射到硬件上并反映其分布式方面。
  • 开发视图(Development View),代表软件在其开发环境中的静态组织,添加了组件、它们的接口和它们相互关联的组合的概念。
  • 场景(Scenario),描述了对象之间和进程之间的交互序列,它们用于识别架构元素并说明和验证架构设计,还可以作为架构原型测试的起点。此视图也称为用例视图。

4+1视图的软件结构。

这种视图的软件架构也可以引入到游戏引擎的架构设计中,比如揭示引擎核心类的UML图便是逻辑视图,引擎的工具链便是开发者视图,资源文件的加载分层和部署方式便是物理视图。

此阶段的引擎已大致成形,架构的组件大致如下所示:

若是细化各个模块,则是如下图所示:

时间来到新世纪,诞生了不少新的渲染引擎或组件,其中就有典型代表Ogre。作为Ogre的衍生引擎Ogre Golf,在Orge的基础上做了不少扩展,引入了许多特性和第三方库,并且研制了代表游戏,例如包含了忍者、机器人、消防栓、城堡、术士等物体的大型迷你高尔夫球场,该游戏支持多人联网互动。

Ogre Golf渲染画面。

在同期,还出现了Irrich、Delta3D、Panda、OSG等引擎,它们各具特色,在引擎的各项特性(渲染、功能、场景、地形、视觉、跨平台等)上的支持程度如下表所示:







此阶段引擎的逻辑循环和渲染循环如下所示:


// 逻辑循环
while (true)
{
for (each frameListener)
{
frameListener.frameStarted();
}
renderCurrentScene();
for (each frameListener)
{
frameListener.frameEnded();
}
finalizeSceneAndSwapBuffers();
} // 渲染循环
while (!quit)
{
// 修改相机属性。
updateCamera();
// 修改场景物体的属性。
updateSceneElements();
// 渲染场景上的物体。
renderScene();
// 呈现交换链(启用多缓冲的情况下)。
swapBuffers();
}

至此,游戏引擎的萌芽期总算顺利完成,逐渐形成了基础的模块、架构和渲染技术。

  • 本篇未完待续。

特别说明

  • 感谢所有参考文献的作者,部分图片来自参考文献和网络,侵删。
  • 本系列文章为笔者原创,只发表在博客园上,欢迎分享本文链接,但未经同意,不允许转载
  • 系列文章,未完待续,完整目录请戳内容纲目
  • 系列文章,未完待续,完整目录请戳内容纲目
  • 系列文章,未完待续,完整目录请戳内容纲目

参考文献

剖析虚幻渲染体系(14)- 延展篇:现代渲染引擎演变史Part 1(萌芽期)的更多相关文章

  1. 《图解UE4渲染体系》Part 1 多线程渲染

    上回书<Part 0 引擎基础>说到,我们粗略地知道UE4是以哪些类来管理一个游戏场景里的数据的,但这仅仅是我们开始探索UE4渲染体系的一小步. 本回主要介绍UE4渲染体系中比较宏观顶层的 ...

  2. 剖析虚幻渲染体系(12)- 移动端专题Part 3(渲染优化)

    目录 12.6 移动端渲染优化 12.6.1 渲染管线优化 12.6.1.1 使用新特性 12.6.1.2 管线优化 12.6.1.3 带宽优化 12.6.2 资源优化 12.6.2.1 纹理优化 1 ...

  3. 剖析虚幻渲染体系(10)- RHI

    目录 10.1 本篇概述 10.2 RHI基础 10.2.1 FRenderResource 10.2.2 FRHIResource 10.2.3 FRHICommand 10.2.4 FRHICom ...

  4. 剖析虚幻渲染体系(13)- RHI补充篇:现代图形API之奥义与指南

    目录 13.1 本篇概述 13.1.1 本篇内容 13.1.2 概念总览 13.1.3 现代图形API特点 13.2 设备上下文 13.2.1 启动流程 13.2.2 Device 13.2.3 Sw ...

  5. 剖析虚幻渲染体系(06)- UE5特辑Part 1(特性和Nanite)

    目录 6.1 本篇概述 6.1.1 本篇内容 6.1.2 基础概念 6.2 UE5新特性 6.2.1 UE5编辑器 6.2.1.1 下载编辑器及资源 6.2.1.2 启动示例工程 6.2.1.3 编辑 ...

  6. 剖析虚幻渲染体系(15)- XR专题

    目录 15.1 本篇概述 15.1.1 本篇内容 15.1.2 XR概念 15.1.2.1 VR 15.1.2.2 AR 15.1.2.3 MR 15.1.2.4 XR 15.1.3 XR综述 15. ...

  7. 剖析虚幻渲染体系(12)- 移动端专题Part 1(UE移动端渲染分析)

    目录 12.1 本篇概述 12.1.1 移动设备的特点 12.2 UE移动端渲染特性 12.2.1 Feature Level 12.2.2 Deferred Shading 12.2.3 Groun ...

  8. 剖析虚幻渲染体系(06)- UE5特辑Part 2(Lumen和其它)

    目录 6.5 Lumen 6.5.1 Lumen技术特性 6.5.1.1 表面缓存(Surface Cache) 6.5.1.2 屏幕追踪(Screen Tracing) 6.5.1.3 Lumen光 ...

  9. 剖析虚幻渲染体系(08)- Shader体系

    目录 8.1 本篇概述 8.2 Shader基础 8.2.1 FShader 8.2.2 Shader Parameter 8.2.3 Uniform Buffer 8.2.4 Vertex Fact ...

随机推荐

  1. linux定时任务 - crontab定时任务

    crontab 定时任务命令 linux 系统则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的计划性工作,因此这个系统服务是默认启动的.另 外, 由于使用者 ...

  2. java笔记:00 数据类型

  3. 2.5 C++STL stack详解

    文章目录 2.5.1引入 2.5.2 代码示例 2.5.3 代码运行结果 总结 2.5.1引入 stack是一种"先进后出"的容器. 不过值得注意的是stack是一种关联容器,是通 ...

  4. vue3-插槽作用域的使用

    当我们在父组件定义了一个数组, data() { return { name: ["lkx", "msx"] } } 想把它传到子组件处理后 props: { ...

  5. Git指令小结

    一.初始化 git config --global user.name "username" 设置git用户名 git config --global user.email &qu ...

  6. 使用VS Code编译Marlin固件

    参考:https://marlinfw.org/docs/basics/install_platformio_vscode.html 前言 在阅读本文之前,您应该已经阅读了使用 PlatformIO ...

  7. Ubuntu16.04 搭建samba服务器

    1昨天花了一天时间弄了NFS服务器,结果搭建完之后出现各种问题,要么挂载不上,要么就是字符乱码.今天在看到一个关于树莓派的介绍的时候,提到Samba服务器的搭建,我尝试了一下,结果发现很顺利地就能够正 ...

  8. 半吊子菜鸟学Web开发1 --配置开发环境

    先说说我自己的情况,我算是一个半吊子菜鸟,对web开发熟练度为0,但是对熟悉C++和Python 所以这里开始记录我学习Web开发的历程,看看我这里学习的程序,能够学到什么地方. 首先是配置环境,我的 ...

  9. TCP和UDP协议?

    TCP(Transmission Control Protocol:传输控制协议:面向连接,可靠传输 UDP(User Datagram Protocol):用户数据报协议:面向无连接,不可靠传输

  10. 请说说Struts1和Struts2的区别?

      特性 Struts1 Struts2 Action Struts1.x要求Action类要扩展自一个抽象基类.Struts1.x的一个共有的问题是面向抽象类编程而不是面向接口编程. Struts2 ...