游戏引擎:游戏引擎剖析(一)

原文作者:Jake Simpson
译者: 向海
Email:[email protected]  
FROM:CSDN

第1部分: 游戏引擎介绍 渲染和构造3D世界


介绍
  自Doom游戏时代以来我们已经走了很远 DOOM不只是款伟大游戏它同时也开创了种新游戏编程模式: 游戏 "引擎" 这种模块化可伸缩和扩展设计观念可以让游戏玩家和设计者深入到游戏核心用新模型场景和声音创造新游戏 或向已有游戏素材中添加新东西大量新游戏根据已经存在游戏引擎开发出来而大多数都以ID公司Quake引擎为基础 这些游戏包括Counter  Strike Team Fortress Tac Ops Strike Force 以及Quake SoccerTac Ops 和Strike Force 都使用了Unreal Tournament 引擎事实上 "游戏引擎" 已经成为游戏玩家的间交流标准用语但是究竟引擎止于何处而游戏又从哪里开始呢?像素渲染声音播放怪物研究以及游戏事件触发游戏中所有这幕后又是什么呢? 如果你曾经研究过这些问题 而且想要知道更多驱动游戏进行东西那么这篇文章正好可以告诉你这些 本文分多个部分深入剖析了游戏引擎内核 特别是Quake引擎我最近工作公司Raven Software已经在Quake引擎基础上开发出了多款游戏其中包括著名Soldier of Fortune   


开始
  让我们首先来看看个游戏引擎和游戏本身的间主要区别 许多人们会混淆游戏引擎和整个游戏 这有点像把个汽车发动机和整个汽车混淆起来 你能够从汽车里面取出发动机 建造另外个外壳再使用发动机 游戏也像那 游戏引擎被定义为所有非游戏特有技术 游戏部份是被称为 '资产' 所有内容 (模型动画声音人工智能和物理学)和为了使游戏运行或者控制如何运行而特别需要代码 比如说AI--人工智能  

  对于曾经看过 Quake 游戏结构人来说 游戏引擎就是 Quakeexe 而游戏部分则是 QAGamedll 和 CGamedll 如果你不知道这是什么意思 也没有什么关系;在有人向我解释它以前 我也不知道是什么意思 但是你将会完全明白它意思 这篇游戏引擎指导分为十个部份 从数量上来说总共是十个部份! 每个部分大概3000字左右现在就从第部分开始我们探索吧深入我们所玩游戏内核在这里我们将了解些基本东西 为后面章节作铺垫


渲染器
  让我们从渲染器来开始游戏引擎设计探讨吧 我们将从游戏开发者(本文作者背景)角度来探讨这些问题事实上在本文各个段落我们将常常从游戏开发者角度探讨 也让您像我们样研究问题!  

  什么是渲染器为什么它又这么重要呢?好吧如果没有它你将什么也看不到它让游戏场景可视化让玩家/观众可以看见场景从而让玩家能够根据屏幕上所看到东西作出适当决断 尽管我们下面探讨可能让新手感到有些恐惧先别去理会它 渲染器做些什么?为什么它是必须?我们将会解释这些重要问题  

  当构造个游戏引擎时候 你通常想做件事情就是建造渲染器 如果看不见任何东西 – 那么你又如何知道你代码在工作呢? 超过 50% CPU 处理时间花费在渲染器上面; 通常也是在这个部分游戏开发者将会受到最苛刻评判 如果我们在这个部分表现很差事情将会变得非常糟糕 我们技术我们游戏和我们公司将在 10 天的内变成业界笑话 它也是我们最依赖于外部厂商和力量地方在这里他们将处理最大限度潜在操作目标 如此说来 建造个渲染器确实不象听起来那么吸引人(事实如此) 但如果没有个好渲染器 游戏或许永远不会跻身于排行榜前10 名  

  如今在屏幕上生成像素涉及到 3D 加速卡 API 3维空间数学 对 3D 硬件如何工作理解等等对於主机(游戏机)游戏来说也需要相同类型知识但是至少对于主机 你不必去尝试击中个移动中目标 台主机硬件配置是固定 "时间快照" 和PC(个人计算机)区别台主机生命期中硬件配置不会改变  

  在般意义上渲染器工作就是要创造出游戏视觉闪光点实际上达到这个目标需要大量窍门技巧3D图形本质上是用最少努力创造出最大效果门艺术 额外 3D 处理在处理器时间和和內存带宽方面都是极为昂贵 它也是种预算 要弄清楚你想在什么地方花费处理器时间而你宁愿在什么地方节省些从而达到最好整体效果 接下来我们将会介绍些这方面工具以及怎样更好用它们让游戏引擎工作


建造3D世界
  最近当我和位从事计算机图形方面工作长达数年的久人会谈时她向我吐露道 当她第次看到实时操纵计算机 3D 图象时 她不知道这是如何实现 也不知道计算机如何能够存储 3D 图象 今天这对于在大街上普通人来说或许是真实即使他们时常玩 PC 游戏 游戏机游戏 或街机游戏

  下面我们将从游戏设计者角度讨论创造 3D 世界些细节你也应该看看 Dave Salvator 所写“3D 管线导论“以便对3D 图象生成主要过程有个整体了解

  3D 物体(对象)被储存成 3D 世界中系列点(被称为顶点) 彼此的间有相互关系所以计算机知道如何在世界中这些点的间画线或者是填充表面 个立方体由8个点组成每个角个点立方体有6个表面 分别代表它个面 这就是 3D 对象储存基础 对于些比较复杂 3D 物体 比如说个 Quake 关卡将有数以千计(有时数以十万计)顶点 和数以千计多边形表面  

  参见上图线框表示(注:原文在这里有幅图) 本质上和上面立方体例子类似 它仅仅是由许许多多小多边形组成些复杂场景模型和世界如何储存是渲染器部份功能 而不属于应用/游戏部份 游戏逻辑不需要知道对象在內存中如何表示 也不需要知道渲染器将怎样把他们显示出来 游戏只是需要知道渲染器将使用正确视野去表示对象 并将在正确动画幀中把正确模型显示出来

  在个好引擎中渲染器应该是可以完全被个新渲染器替换掉 并且不需要去改动游戏行代码许多跨平台引擎 而且许多自行开发游戏机引擎就是这样如 Unreal 引擎 --举例来说 这个游戏 GameCube 版本渲染器就可以被你任意替换掉  

  让我们再看看内部表示思路方法—除了使用坐标系统还有其他思路方法可以在计算机內存里表示空间在数学上你可以使用个方程式来描述直线或曲线 并得到多边形 而几乎所有 3D 显示卡都使用多边形来作为它们最终渲染图元 个图元就是你在任何显示卡上面所能使用最低级绘制(渲染)单位几乎所有硬件都是使用 3个顶点多边形( 3角形) nVidia 和 ATI 显卡可以允许你以数学方式渲染(被称为高次表面)这不是所有图形卡标准 你还不能靠它作为渲染策略

  从计算角度来看这通常有些昂贵但它时常是新实验技术基础例如地表渲染或者对物件锐利边缘进行柔化 我们将会在下面曲面片小节中更进步介绍这些高次表面


剔除概观
  问题来了 我现在有个由几十万个顶点/多边形描述世界 我以第人称视角位于我们这个 3D 世界 在视野中可以看见世界些多边形 而另外些则不可见 些物体 比如面看得见墙壁 遮挡住了它们 即使是最好游戏编码人员 在目前 3D 显卡上个视野中也不能处理 300000个 3角形且仍然维持 60fps (个主要目标) 显卡不能处理它 因此我们必须写些代码在把它们交给显卡处理的前除去那些看不见多边形 这个过程被称为剔除

  有许多区别剔除思路方法 在深入了解这些的前让我们探讨下为什么图形显示卡不能处理超高数量多边形 我是说最新图形卡每秒钟不能处理几百万个多边形吗?它不应该能够处理吗? 首先你必须理解市场销售宣称多边形生成率和真实世界多边形生成率 行销上宣称多边形生成率是图形显示卡理论上能够达到多边形生成率  

  如果全部多边形都在屏幕上 相同纹理相同尺寸大小 正在往显示卡上传送多边形应用除了传送多边形以外什么也不做 这时显卡能处理多少多边形数量 就是图形芯片厂商呈现给你数字  

  然而在真实游戏情形中应用时常在后台做着许多其他事情 -- 多边形 3D 变换 光照计算 拷贝较多纹理到显卡內存 等等 不仅纹理要送到显示卡 而且还有每个多边形细节些比较新显卡允许你实际上在显卡內存本身里面储存模型/世界几何细节 但这可能是昂贵将会耗光纹理正常可以使用空间所以你最好能确定每幀都在使用这些模型顶点 否则你只是在浪费显示卡上存储空间 我们就说到这里了 重要在实际使用显卡时并不必然就能达到你在显卡包装盒上所看到那些指标如果你有个比较慢速CPU 或没有足够內存时这种差异就尤为真实


基本剔除思路方法
  最简单剔除方式就是把世界分成区域 每个区域有个其他可见区域列表 那样 你只需要显示针对任何给定点可见部分 如何生成可见视野区域列表是窍门技巧所在 再者 有许多思路方法可以用来生成可见区域列表 如 BSP 树 窥孔等等  

  可以肯定当谈论 DOOM 或 QUAKE 时你已经听到过使用 BSP 这个术语了 它表示 2叉空间分割  

  BSP 是种将世界分成小区域思路方法通过组织世界多边形容易确定哪些区域是可见而哪些是不可见 – 从而方便了那些不想做太多绘制工作基于软件Software渲染器它同时也以种非常有效方式让你知道你位于世界中什么地方  

  在基于窥孔引擎 ( 最早由 3D Realms 已经取消 Prey 项目引入游戏世界 )里每个区域 ( 或房间) 都建造有自己模型 通过每个区域门 ( 或窥孔 )能够看见另外区段 渲染器把每个区域作为独立场景单独绘制 这就是它大致原理 足以说这是任何个渲染器必需部份而且非常重要  

  尽管些这样技术归类在 "遮挡剔除"的下但是他们全部都有同样: 尽早消除不必要工作 对於个FPS游戏(第人称射击游戏) 来说视野中时常有许多 3角形而且游戏玩家承担视野控制丢弃或者剔除不可见 3角形就是绝对必要 对空间模拟来说也是这样 你可以看见很远很远地方 – 剔除超过视觉范围外面东西就非常重要 对于视野受到限制游戏来说 – 比如 RTS (即时战略类游戏)--通常比较容易实现 通常渲染器这个部份还是由软件Software来完成 而不是由显卡完成 由显卡来做这部分工作只是个时间问题


基本图形管线流程
  个简单例子从游戏到多边形绘制图形管线过程大致是这样:
    · 游戏决定在游戏中有哪些对象 它们模型 使用纹理 他们可能在什么动画幀以及它们在游戏世界里位置 游戏也决定照相机位置和方向

    · 游戏把这些信息传递给渲染器以模型为例 渲染器首先要查看模型大小 照相机位置 然後决定模型在屏幕上是否全部可见 或者在观察者 (照相机视野) 左边在观察者后面或距离很远而不可见它甚至会使用些世界测定方式来计算出模型是否是可见 (参见下面这条)

    · 世界可视化系统决定照相机在世界中位置并根据照相机视野决定世界哪些区域 / 多边形是可见有许多思路方法可以完成这个任务 包括把世界分割成许多区域暴力思路方法每个区域直接为"我能从区域 D 看见区域 AB & C" 到更精致 BSP( 2叉空间分割)世界 所有通过这些剔除测试多边形被传递给多边形渲染器进行绘制  

    · 对於每个被传递给渲染器多边形 渲染器依照局部数学 ( 也就是模型动画) 和世界数学(相对于照相机位置?)对多边形进行变换并检查决定多边形是不是背对相机 (也就是远离照相机)背面多边形被丢弃 非背面多边形由渲染器根据发现附近灯光照亮然后渲染器要看多边形使用纹理并且确定 API/ 图形卡正在使用那种纹理作为它渲染基础 在这里多边形被送到渲染 API然后再送给显卡  

  很明显这有些过分简单化了但你大概理解了 下面图表摘自Dave Salvator's 3D 管线可以给你多些具体细节:  

  3D 管线
  - 高层概观
   1. 应用/ 场景
  ·场景/ 几何数据库遍历
  ·对象运动观察相机运动和瞄准
  ·对象模型动画运动
  ·3D 世界内容描述
  ·对象可见性检查包括可能遮挡剔除
  ·细节层次选择 (LOD)

  2. 几何
  ·变换 (旋转平移 缩放)
  ·从模型空间到世界空间变换 (Direct3D)
  ·从世界空间到观察空间变换
  ·观察投影
  ·细节接受/ 拒绝 剔除
  ·背面剔除 (也可以在后面屏幕空间中做)
  光照
  ·透视分割 - 变换到裁剪空间
  ·裁剪
  ·变换到屏幕空间

  3. 3角形生成
  ·背面剔除 ( 或者在光照计算的前观察空间中完成)
  ·斜率/ 角度计算
  ·扫瞄线变换

  4. 渲染 / 光栅化
  ·着色
  ·纹理
  ·雾
  ·Alpha 透明测试
  ·深度缓冲
  ·抗锯齿 (可选择)
  ·显示

  通常你会把所有多边形放到些列表内 然後根据纹理对这个列表排序(这样你只需要对显卡传送次纹理 而不是每个多边形都传送次) 等等在过去会把多边形按照它们到相机距离进行排序首先绘制那些距离相机最远多边形 但现在由于 Z 缓冲出现这种思路方法就不是那么重要了 当然那些透明多边形要除外它们要在所有非半透明多边形绘制的后才能够绘制 这样所有在它们后面多边形就能正确地在场景中显现出来 当然象那样实际上你必须得从后到前地绘制那些多边形 但时常在任何给定 FPS 游戏场景中 通常没有太多透明多边形 它可能看起来像有但实际上和那些不透明多边形相比其比率是相当低  

  旦应用将场景传递到 API API 就能利用硬件加速变换和光照处理 (T&L) 这在如今 3D 显卡中是很平常事情 这里不讨论涉及到矩阵数学(参见Dave 3D 管线导论)几何变换允许 3D 显卡按照你尝试根据相机在任何时间位置和方向在世界正确角度和位置绘制多边形  

  对于每个点或顶点都有大量计算 包括裁剪运算决定任何给定多边形实际上是否可见在屏幕上完全不可见或部分可见 光照运算计算纹理色彩明亮程度这取决于世界灯光从什么角度如何投射到顶点上 过去处理器处理这些计算但现在当代图形硬件就能为你做这些事情 这意谓着你处理器可以去做其他事情了很明显这是件好事情 (tm) 由于不能指望市面上所有 3D 显卡板上都有T & L 所以无论如何你自己将必须写所有这些例程 (再次从游戏开发者角度来说) 你将在本文各处区别段落看到 "好事情 ( tm)" 这个词汇 我认为这些特征为使游戏看起来更好作出了非常有用贡献 毫不令人吃惊你也将会看见它对立面;你猜到了那就是“坏事情 (tm)” 我正在尝试争取这些词汇版权 你要使用他们就得支付笔小小费用哟


曲面片(高次表面)
  除了 3角形曲面片使用现在正变得更普遍 他们能用数学表达式来描述几何 ( 通常涉及某种曲线几何形体) 而不仅仅只是列出大量多边形以及在游戏世界中位置 所以曲面片 ( 高次表面个名称) 非常好 这样你实际上就能够动态地根据方程式来建立( 和变形 )多边形网格 并决定你实际想要从曲面片上看到多边形数量 因此举例来说你可以描述个管道 然后在世界中就可以有这种管道许多样例些房间中 你已经显示了 10000个多边形你可以说"我们已经显示了大量多边形而且任何更多多边形将会使幀速率下降 所以这个管道应该只有 100 个多边形" 但在另外个房间中 视野中只有 5000个可见多边形你可以说"我们还没有达到预算可以显示多边形数量 所以现在这个管道能有 500 个多边形" 非常美妙东西 --但你必须首先知道所有这些并建立网格这不是无足轻重 通过 AGP 传送同个对象曲面方程确实要比传送其大量顶点节省成本 SOF2 就使用了这个思路方法种变体来建立它地表系统

  事实上现在 ATI 显卡具有 TruForm 它能带个以 3角形为基础模型并将该模型转换为基于高次表面模型使其平滑 — 接着再用十倍 3角形数量把模型转换回基于大量 3角形模型 (被称为retesselation)然后模型送往管线做进处理 实际上 ATI 仅仅在 T & L 引擎的前增加了个阶段来处理这个过程这里缺点是要控制哪些模型需要被平滑处理而哪些又不需要你常常想要些边缘比较尖锐 比如鼻子但它却被不恰当平滑过了 这仍然是种很好技术而且我能预见它在将来会被更多应用  

  这就是第部份 -- 我们将会在第 2部分继续介绍光照和纹理下面章节会更加深入  
Tags:  游戏搜索引擎 游戏引擎启动异常 什么是游戏引擎 游戏引擎

延伸阅读

最新评论

发表评论