游戏引擎剖析(一)【游戏编程吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:10,189贴子:
游戏引擎剖析(一)收藏
游戏引擎剖析
游戏引擎剖析
原文作者:Jake Simpson
译者: 向海
第1部分: 游戏引擎介绍, 渲染和构造3D世界
自Doom游戏时代以来我们已经走了很远。 DOOM不只是一款伟大的游戏,它同时也开创了一种新的游戏编程模式: 游戏 "引擎"。
这种模块化,可伸缩和扩展的设计观念可以让游戏玩家和程序设计者深入到游戏核心,用新的模型,场景和声音创造新的游戏, 或向已有的游戏素材中添加新的东西。大量的新游戏根据已经存在的游戏引擎开发出来,而大多数都以ID公司的Quake引擎为基础, 这些游戏包括Counter Strike, Team Fortress, Tac Ops, Strike Force, 以及Quake Soccer。
Tac Ops 和Strike Force 都使用了Unreal Tournament 引擎。事实上, "游戏引擎" 已经成为游戏玩家之间交流的标准用语,但是究竟引擎止于何处,而游戏又从哪里开始呢?像素的渲染,声音的播放,怪物的思考以及游戏事件的触发,游戏中所有这一切的幕后又是什么呢? 如果你曾经思考过这些问题, 而且想要知道更多驱动游戏进行的东西,那么这篇文章正好可以告诉你这些。
本文分多个部分深入剖析了游戏引擎的内核, 特别是Quake引擎,因为我最近工作的公司Raven Software已经在Quake引擎的基础上开发出了多款游戏,其中包括著名的Soldier of Fortune 。
让我们首先来看看一个游戏引擎和游戏本身之间的主要区别。 许多人们会混淆游戏引擎和整个游戏
。这有点像把一个汽车发动机和整个汽车混淆起来一样
。 你能够从汽车里面取出发动机, 建造另外一个外壳,再使用发动机一次。 游戏也像那。 游戏引擎被定义为所有的非游戏特有的技术。 游戏部份是被称为 '资产' 的所有内容 (模型,动画,声音,人工智能和物理学)和为了使游戏运行或者控制如何运行而特别需要的程序代码, 比如说AI--人工智能。
对于曾经看过 Quake 游戏结构的人来说,
游戏引擎就是 Quake。exe ,而游戏部分则是 QAGame。dll和 CGame。dll 。 如果你不知道这是什么意思, 也没有什么关系;在有人向我解释它以前, 我也不知道是什么意思。 但是你将会完全明白它的意思。
这篇游戏引擎指导分为十一个部份。 是的, 从数量上来说,总共是十一个部份! 每个部分大概3000字左右。现在就从第一部分开始我们的探索吧,深入我们所玩游戏的内核,在这里我们将了解一些基本的东西, 为后面的章节作铺垫。。。
让我们从渲染器来开始游戏引擎设计的探讨吧, 我们将从游戏开发者(本文作者的背景)的角度来探讨这些问题。事实上,在本文的各个段落,我们将常常从游戏开发者的角度探讨,
也让您像我们一样思考问题!
什么是渲染器,为什么它又这么重要呢?好吧,如果没有它,你将什么也看不到。它让游戏场景可视化,让玩家/观众可以看见场景,从而让玩家能够根据屏幕上所看到的东西作出适当的决断。 尽管我们下面的探讨可能让新手感到有些恐惧,先别去理会它。
渲染器做些什么?为什么它是必须的?我们将会解释这些重要问题。
当构造一个游戏引擎的时候, 你通常想做的第一件事情就是建造渲染器。 因为如果看不见任何东西
- 那么你又如何知道你的程序代码在工作呢? 超过 50% 的 CPU 处理时间花费在渲染器上面; 通常也是在这个部分,游戏开发者将会受到最苛刻的评判。 如果我们在这个部分表现很差,事情将会变得非常糟糕,
我们的程序技术,我们的游戏和我们的公司将在 10 天之内变成业界的笑话。
它也是我们最依赖于外部厂商和力量的地方,在这里他们将处理最大限度的潜在操作目标。 如此说来, 建造一个渲染器确实不象听起来那么吸引人(事实如此), 但如果没有一个好的渲染器,
游戏或许永远不会跻身于排行榜前10 名。
如今,在屏幕上生成像素,涉及到 3D 加速卡, API ,三维空间数学, 对 3D 硬件如何工作的理解等等。对於主机(游戏机)游戏来说,也需要相同类型的知识,但是至少对于主机,
来火星时代学习游戏编程,强大美术资源,多年游戏教学实力,20000家合作企业,毕业=就业,火星时代游戏编程,业界精英一对一辅导,参与游戏实训项目,工作经验不再是零.
你不必去尝试击中一个移动中的目标。 因为一台主机的硬件配置是固定的 "时间快照", 和PC(个人计算机)不同, 在一台主机的生命期中,它的硬件配置不会改变。
在一般意义上,渲染器的工作就是要创造出游戏的视觉闪光点,实际上达到这个目标需要大量的技巧。3D图形本质上是用最少的努力创造出最大效果的一门艺术, 因为额外的 3D 处理在处理器时间和和内存带宽方面都是极为昂贵的。
它也是一种预算, 要弄清楚你想在什么地方花费处理器时间,而你宁愿在什么地方节省一些从而达到最好的整体效果。 接下来我们将会介绍一些这方面的工具,以及怎样更好的用它们让游戏引擎工作。
建造3D世界
最近,当我和一位从事计算机图形方面工作长达数年之久的人会谈时,她向我吐露道,
当她第一次看到实时操纵计算机 3D 图象时, 她不知道这是怎么实现的, 也不知道计算机如何能够存储 3D 图象。 今天这对于在大街上的普通人来说或许是真实的,即使他们时常玩 PC 游戏,
游戏机游戏, 或街机游戏。
下面我们将从游戏设计者的角度讨论创造 3D 世界的一些细节,你也应该看一看 Dave Salvator 所写的“3D 管线导论“,以便对3D 图象生成的主要过程有一个整体的了解。
3D 物体(对象)被储存成 3D 世界中的一系列点(被称为顶点), 彼此之间有相互关系,所以计算机知道如何在世界中的这些点之间画线或者是填充表面。
一个立方体由8个点组成,每个角一个点。立方体有 6个表面, 分别代表它的每一个面。
这就是 3D 对象储存的基础。 对于一些比较复杂的 3D 物体,
比如说一个 Quake 的关卡,将有数以千计(有时数以十万计)的顶点, 和数以千计的多边形表面。
参见上图的线框表示(注:原文在这里有一幅图)。
本质上与上面的立方体例子类似, 它仅仅是由许许多多的小多边形组成的一些复杂场景。
模型和世界如何储存是渲染器的一部份功能, 而不属于应用程序/游戏部份。 游戏逻辑不需要知道对象在内存中如何表示, 也不需要知道渲染器将怎样把他们显示出来。 游戏只是需要知道渲染器将使用正确的视野去表示对象,
并将在正确的动画帧中把正确的模型显示出来。
在一个好的引擎中,渲染器应该是可以完全被一个新的渲染器替换掉, 并且不需要去改动游戏的一行代码。许多跨平台引擎, 而且许多自行开发的游戏机引擎就是这样的,如 Unreal 引擎, --举例来说,这个游戏 GameCube 版本的渲染器就可以被你任意的替换掉。
让我们再看看内部的表示方法--除了使用坐标系统,还有其他方法可以在计算机内存里表示空间的点。
在数学上,你可以使用一个方程式来描述直线或曲线, 并得到多边形, 而几乎所有的 3D 显示卡都使用多边形来作为它们的最终渲染图元。 一个图元就是你在任何显示卡上面所能使用的最低级的绘制(渲染)单位,几乎所有的硬件都是使用三个顶点的多边形(三角形)。 新一代的 nVidia 和 ATI 显卡可以允许你以数学方式渲染(被称为高次表面), 但因为这不是所有图形卡的标准, 你还不能靠它作为渲染策略。
从计算的角度来看,这通常有些昂贵,但它时常是新的实验技术的基础, 例如, 地表的渲染,
或者对物件锐利的边缘进行柔化。 我们将会在下面的曲面片小节中更进一步介绍这些高次表面。
问题来了。 我现在有一个由几十万个顶点/多边形描述的世界。 我以第一人称视角位于我们这个 3D 世界的一边。 在视野中可以看见世界的一些多边形,
而另外一些则不可见, 因为一些物体, 比如一面看得见的墙壁, 遮挡住了它们。 即使是最好的游戏编码人员, 在目前的 3D 显卡上,
在一个视野中也不能处理 300,000个三角形且仍然维持 60fps (一个主要目标)。
显卡不能处理它, 因此我们必须写一些代码,在把它们交给显卡处理之前除去那些看不见的多边形。 这个过程被称为剔除。
有许多不同的剔除方法。 在深入了解这些之前,让我们探讨一下为什么图形显示卡不能处理超高数量的多边形。 我是说,最新的图形卡每秒钟不能处理几百万个多边形吗?它不应该能够处理吗? 首先,你必须理解市场销售宣称的多边形生成率和真实世界的多边形生成率。 行销上宣称的多边形生成率是图形显示卡理论上能够达到的多边形生成率。
如果全部多边形都在屏幕上, 相同的纹理,相同的尺寸大小, 正在往显示卡上传送多边形的应用程序除了传送多边形以外什么也不做,
这时显卡能处理多少多边形数量, 就是图形芯片厂商呈现给你的数字。
然而,在真实的游戏情形中,应用程序时常在后台做着许多其他的事情 -- 多边形的 3D 变换, 光照计算, 拷贝较多的纹理到显卡内存, 等等。
不仅纹理要送到显示卡, 而且还有每个多边形的细节。一些比较新的显卡允许你实际上在显卡内存本身里面储存模型/世界几何细节,
但这可能是昂贵的,将会耗光纹理正常可以使用的空间,所以你最好能确定每一帧都在使用这些模型的顶点, 否则你只是在浪费显示卡上的存储空间。 我们就说到这里了。 重要的是,在实际使用显卡时,并不必然就能达到你在显卡包装盒上所看到的那些指标,如果你有一个比较慢速的CPU , 或没有足够的内存时,这种差异就尤为真实。
基本的剔除方法
最简单的剔除方式就是把世界分成区域, 每个区域有一个其他可见区域的列表。
那样, 你只需要显示针对任何给定点的可见部分。 如何生成可见视野区域的列表是技巧所在。 再者, 有许多方法可以用来生成可见区域列表, 如 BSP 树, 窥孔等等。
可以肯定,当谈论 DOOM 或 QUAKE 时,你已经听到过使用 BSP 这个术语了。 它表示二叉空间分割。
BSP 是一种将世界分成小区域的的方法,通过组织世界的多边形,容易确定哪些区域是可见的而哪些是不可见的 - 从而方便了那些不想做太多绘制工作的基于软件的渲染器。它同时也以一种非常有效的方式让你知道你位于世界中的什么地方。
在基于窥孔的引擎 ( 最早由 3D Realms 已经取消的 Prey 项目引入游戏世界 )里,每个区域 ( 或房间) 都建造有自己的模型,
通过每个区域的门 ( 或窥孔 )能够看见另外的区段。 渲染器把每个区域作为独立的场景单独绘制。
这就是它的大致原理。 足以说这是任何一个渲染器的必需部份,而且非常重要。
尽管一些这样的技术归类在 "遮挡剔除"之下,但是他们全部都有同样的目的: 尽早消除不必要的工作。
对於一个FPS游戏(第一人称射击游戏) 来说,视野中时常有许多三角形,而且游戏玩家承担视野的控制,丢弃或者剔除不可见的三角形就是绝对必要的了。
对空间模拟来说也是这样的, 你可以看见很远很远的地方 - 剔除超过视觉范围外面的东西就非常重要。 对于视野受到限制的游戏来说 - 比如 RTS (即时战略类游戏)--通常比较容易实现。 通常渲染器的这个部份还是由软件来完成,
而不是由显卡完成, 由显卡来做这部分工作只是一个时间问题。
基本的图形管线流程
一个简单的例子,从游戏到多边形绘制的图形管线过程大致是这样:
? 游戏决定在游戏中有哪些对象, 它们的模型, 使用的纹理, 他们可能在什么动画帧,以及它们在游戏世界里的位置。
游戏也决定照相机的位置和方向。
? 游戏把这些信息传递给渲染器。以模型为例 ,渲染器首先要查看模型的大小 ,照相机的位置, 然后决定模型在屏幕上是否全部可见, 或者在观察者 (照相机视野) 的左边,在观察者的后面,或距离很远
而不可见。它甚至会使用一些世界测定方式来计算出模型是否是可见的。 (参见下面这条)
? 世界可视化系统决定照相机在世界中的位置,并根据照相机视野决定世界的哪些区域 / 多边形是可见的。有许多方法可以完成这个任务, 包括把世界分割成许多区域的暴力方法,每个区域直接为"我能从区域 D 看见区域
所以曲面片 ( 高次表面的另一个名称) 非常好。 这样,你实际上就能够动态地根据方程式来建立( 和变形 )多边形网格, 并决定你实际想要从曲面片上看到的多边形数量。 因此,举例来说,你可以描述一个管道,
然后在世界中就可以有这种管道的许多样例。 在一些房间中, 你已经显示了 10,000个多边形,你可以说,"因为我们已经显示了大量的多边形,而且任何更多的多边形将会使帧速率下降,
所以这个管道应该只有 100 个多边形"。 但在另外一个房间中,
视野中只有 5,000个可见的多边形,你可以说,"因为我们还没有达到预算可以显示的多边形数量 , 所以,现在这个管道能有
500 个多边形"。 非常美妙的东西 --但你必须首先知道所有这些,并建立网格,这不是无足轻重的。
通过 AGP 传送同一个对象的曲面方程确实要比传送其大量顶点节省成本。
SOF2 就使用了这个方法的一种变体来建立它的地表系统。
事实上现在的 ATI 显卡具有 TruForm, 它能带一个以三角形为基础的模型,并将该模型转换为基于高次表面的模型,使其平滑 -- 接着再用十倍三角形数量把模型转换回基于大量三角形的模型 (被称retesselation)。然后模型送往管线做进一步的处理。 实际上 ATI 仅仅在 T & L 引擎之前增加了一个阶段来处理这个过程。这里的缺点是,要控制哪些模型需要被平滑处理而哪些又不需要。你常常想要一些边缘比较尖锐,
比如鼻子,但它却被不恰当的平滑过了。 这仍然是一种很好的技术,而且我能预见它在将来会被更多的应用。
这就是第一部份 -- 我们将会在第二部分继续介绍光照和纹理,下面的章节会更加深入。
第 2 部份: 3D环境的光照和纹理
世界的灯光
在变换过程中, 通常是在称为观察空间的坐标空间中, 我们遇到了最重要的运算之一: 光照计算。 它是一种这样的事情, 当它工作时,你不关注它,但当它不工作时, 你就非常关注它了。有很多不同的光照方法,从简单的计算多边形对于灯光的朝向,并根据灯光到多边形的方向和距离加上灯光颜色的百分比值,一直到产生边缘平滑的灯光贴图叠加基本纹理。而且一些 API 实际上提供预先建造的光照方法。举例来说,OpenGL 提供了每多边形,每顶点,和每像素的光照计算。
在顶点光照中,你要决定一个顶点被多少个多边形共享,并计算出共享该顶点的所有多边形法向量的均值(称为法向量),并将该法向量赋顶点。一个给定多边形的每个顶点会有不同的法向量,所以你需要渐变或插值多边形顶点的光照颜色以便得到平滑的光照效果。
你没有必要用这种光照方式查看每个单独的多边形。 这种方式的优点是时常可以使用硬件转换与光照(T & L)来帮助快速完成。 不足之处是它不能产生阴影。 举例来说,即使灯光是在模型的右侧,左手臂应该在被身体投影的阴影中,而实际上模型的双臂却以同样的方式被照明了。
这些简单的方法使用着色来达到它们的目标。 当用平面光照绘制一个多边形时, 你让渲染(绘制)引擎把整个多边形都着上一种指定的颜色。这叫做平面着色光照。 (该方法中,多边形均对应一个光强度,表面上所有点都用相同的强度值显示,渲染绘制时得到一种平面效果,多边形的边缘不能精确的显示出来) 。
对于顶点着色 ( Gouraud 着色) ,你让渲染引擎给每个顶点赋予特定的颜色。 在绘制多边形上各点投影所对应的像素时,根据它们与各顶点的距离,对这些顶点的颜色进行插值计算。 (实际上Quake III 模型使用的就是这种方法, 效果好的令人惊奇)。
还有就是 Phong 着色。如同 Gouraud 着色,通过纹理工作,但不对每个顶点颜色进行插值决定像素颜色值, 它对每个顶点的法向量进行插值,会为每个顶点投影的像素做相同的工作。对于 Gouraud 着色,你需要知道哪些光投射在每个顶点上。对于 Phong 着色,你对每个像素也要知道这么多。
一点也不令人惊讶, Phong 着色可以得到更加平滑的效果,因为每个像素都需要进行光照计算,其绘制非常耗费时间。平面光照处理方法很快速,
但比较粗糙。Phong 着色比 Gouraud 着色计算更昂贵,但效果最好,可以达到镜面高光效果("高亮")。 这些都需要你在游戏开发中折衷权衡。
不同的灯光
接着是生成照明映射,你用第二个纹理映射(照明映射)与已有的纹理混合来产生照明效果。这样工作得很好,
但这本质上是在渲染之前预先生成的一种罐装效果。如果你使用动态照明 (即,灯光移动, 或者没有程序的干预而打开和关闭),你得必须在每一帧重新生成照明映射,按照动态灯光的运动方式修改这些照明映射。灯光映射能够快速的渲染,但对存储这些灯光纹理所需的内存消耗非常昂贵。你可以使用一些压缩技巧使它们占用较少的的内存空间,或减少其尺寸大小,
甚至使它们是单色的 (这样做就不会有彩色灯光了),等等。 如果你确实在场景中有多个动态灯光,
重新生成照明映射将以昂贵的CPU周期而告终。
许多游戏通常使用某种混合照明方式。
以Quake III为例,场景使用照明映射, 动画模型使用顶点照明。 预先处理的灯光不会对动画模型产生正确的效果 -- 整个多边形模型得到灯光的全部光照值 -- 而动态照明将被用来产生正确的效果。
使用混合照明方式是多数的人们没有注意到的一个折衷,它通常让效果看起来"正确"。 这就是游戏的全部 - 做一切必要的工作让效果看起来"正确",但不必真的是正确的。
当然,所有这些在新的Doom引擎里面都不复存在了,但要看到所有的效果,至少需要 1GHZ CPU 和 GeForce 2 显卡。是进步了,但一切都是有代价的。
一旦场景经过转换和照明, 我们就进行裁剪运算。
不进入血淋淋的细节而,剪断运算决定哪些三角形完全在场景 (被称为观察平截头体)
之内或部份地在场景之内。完全在场景之内的三角形被称为细节接受,它们被处理。对于只是部分在场景之内的三角形, 位于平截头体外面的部分将被裁剪掉,余下位于平截头体内部的多边形部分将需要重新闭合,以便其完全位于可见场景之内。 (更多的细节请参考我们的 3D 流水线指导一文)。
场景经过裁剪以后,流水线中的下一个阶段就是三角形生成阶段(也叫做扫描 线转换),场景被映射到2D
屏幕坐标。到这里,就是渲染(绘制)运算了。
纹理与MIP映射
纹理在使3D场景看起来真实方面异常重要,它们是你应用到场景区域或对象的一些***成多边形的小图片。多重纹理耗费大量的内存,有不同的技术来帮助管理它们的尺寸大小。纹理压缩是在保持图片信息的情况下,让纹理数据更小的一种方法。纹理压缩占用较少的游戏CD空间,更重要的是,占用较少内存和3D 显卡存储空间。另外,在你第一次要求显卡显示纹理的时候,压缩的(较小的) 版本经过 AGP 接口从 PC 主存送到3D 显卡, 会更快一些。纹理压缩是件好事情。 在下面我们将会更多的讨论纹理压缩。
MIP 映射(多纹理映射)
游戏引擎用来减少纹理内存和带宽需求的另外一个技术就是 MIP 映射。
MIP 映射技术通过预先处理纹理,产生它的多个拷贝纹理,每个相继的拷贝是上一个拷贝的一半大小。为什么要这样做?要回答这个问题,你需要了解 3D 显卡是如何显示纹理的。最坏情况,你选择一个纹理,贴到一个多边形上,然后输出到屏幕。我们说这是一对一的关系,最初纹理映射图的一个纹素 (纹理元素) 对应到纹理映射对象多边形的一个像素。如果你显示的多边形被缩小一半,纹理的纹素就每间隔一个被显示。这样通常没有什么问题 -- 但在某些情况下会导致一些视觉上的怪异现象。让我们看看砖块墙壁。 假设最初的纹理是一面砖墙,有许多砖块,砖块之间的泥浆宽度只有一个像素。如果你把多边形缩小一半,
纹素只是每间隔一个被应用,这时候,所有的泥浆会突然消失,因为它们被缩掉了。你只会看到一些奇怪的图像。
使用 MIP 映射,你可以在显示卡应用纹理之前,自己缩放图像,因为可以预先处理纹理,你做得更好一些,让泥浆不被缩掉。当 3D 显卡用纹理绘制多边形时,它检测到缩放因子,说,"你知道,我要使用小一些的纹理,而不是缩小最大的纹理,这样看起来会更好一些。" 在这里, MIP 映射为了一切,一切也为了 MIP 映射。
多重纹理与凹凸映射
单一纹理映射给整个3D 真实感图形带来很大的不同, 但使用多重纹理甚至可以达到一些更加令人难忘的效果。过去这一直需要多遍渲染(绘制),严重影响了像素填充率。
但许多具有多流水线的3D 加速卡,如ATI's Radeon 和 nVidia's GeForce 2及更高级的显卡,多重纹理可以在一遍渲染(绘制)过程中完成。 产生多重纹理效果时, 你先用一个纹理绘制多边形,然后再用另外一个纹理透明地绘制在多边形上面。这让你可以使纹理看上去在移动,或脉动,
甚至产生阴影效果 (我们在照明一节中描述过)。绘制第一个纹理映射,然后在上面绘制带透明的全黑纹理,引起一种是所有的织法黑色的但是有一个透明分层堆积过它的顶端
, 这就是 -- 即时阴影。 该技术被称为照明映射 ( 有时也称为
暗映射),直至新的Doom ,一直是Id引擎里关卡照明的传统方法。
凹凸贴图是最近涌现出来的一种古老技术。几年以前 Matrox 第一个在流行的 3D 游戏中发起使用各种不同形式的凹凸贴图。就是生成纹理来表现灯光在表面的投射,表现表面的凹凸或表面的裂缝。
凹凸贴图并不随着灯光一起移动 -- 它被设计用来表现一个表面上的细小瑕疵,而不是大的凹凸。 比如说,在飞行模拟器中,你可以使用凹凸贴图来产生像是随机的地表细节,而不是重复地使用相同的纹理,看上去一点趣味也没有。
凹凸贴图产生相当明显的表面细节,尽管是很高明的戏法,但严格意义上讲,凹凸贴图并不随着你的观察角度而变化。比较新的 ATI 和 nVidia 显卡片能执行每像素运算,这种缺省观察角度的不足就真的不再是有力而快速的法则了。
无论是哪一种方法, 到目前为止,没有游戏开发者太多的使用; 更多的游戏能够且应该使用凹凸贴图。
高速缓存抖动 = 糟糕的事物
纹理高速缓存的管理游戏引擎的速度至关重要。
和任何高速缓存一样,缓存命中很好,而不命中将很糟糕。如果遇到纹理在图形显示卡内存被频繁地换入换出的情况,这就是纹理高速缓存抖动。发生这种情况时,通常API将会废弃每个纹理,结果是所有的纹理在下一帧将被重新加载,这非常耗时和浪费。对游戏玩家来说,当API重新加载纹理高速缓存时,会导致帧速率迟钝。
在纹理高速缓存管理中,有各种不同的技术将纹理高速缓存抖动减到最少
- 这是确保任何 3D 游戏引擎速度的一个决定性因素。 纹理管理是件好事情 - 这意味着只要求显卡使用纹理一次,而不是重复使用。这听起来有点自相矛盾,但效果是它意谓着对显卡说,"看, 所有这些多边形全部使用这一个纹理,我们能够仅仅加载这个纹理一次而不是许多次吗?" 这阻止API ( 或图形驱动软件) 上传多次向显卡加载纹理。象OpenGL这样的API实际上通常处理纹理高速缓存管理,意谓着,根据一些规则,比如纹理存取的频率,API决定哪些纹理储存在显卡上,哪些纹理存储在主存。
真正的问题来了:a) 你时常无法知道API正在使用的准确规则。
b)你时常要求在一帧中绘制更多的纹理,以致超出了显卡内存空间所能容纳的纹理。
另外一种纹理高速缓存管理技术是我们早先讨论的纹理压缩。很象声音波形文件被压缩成
MP3 文件,尽管无法达到那样的压缩比率,但纹理可以被压缩。
从声音波形文件到MP3的压缩可以达到 11:1的压缩比率,而绝大多数硬件支持的纹理压缩运算法则只有 4:1 的压缩比率,尽管如此,这样能产生很大的差别。 除此之外,在渲染(绘制)过程中,只有在需要时,硬件才动态地对纹理进行解压缩。这一点非常棒,我们仅仅擦除即将可能用到的表面。
如上所述,另外一种技术确保渲染器要求显卡对每个纹理只绘制一次。确定你想要渲染(绘制)的使用相同纹理的所有多边形同时送到显卡,而不是一个模型在这里,另一个模型在那里,然后又回到最初的纹理论。仅仅绘制一次,你也就通过AGP接口传送一次。Quake III 在其阴影系统就是这么做的。处理多边形时,把它们加入到一个内部的阴影列表,一旦所有的多边形处理完毕,渲染器遍历纹理列表,就将纹理及所有使用这些纹理的多边形同时传送出去。
上述过程在使用显卡的硬件 T & L(如果支持的话)时,并不怎么有效。你面临的结局是,满屏幕都是使用相同纹理的大量的多边形小群组,所有多边形都使用不同的变换矩阵。这意谓着更多的时间花在建立显卡的硬件 T & L 引擎 ,更多的时间被浪费了。 无论如何,因为他们有助于对整个模型使用统一的纹理,所以它对实际屏幕上的模型可以有效地工作。但是因为许多多边形倾向使用相同的墙壁纹理,所以对于世界场景的渲染,它常常就是地狱。通常它没有这么严重,因为大体而言,世界的纹理不会有那么大,这样一来API的纹理缓存系统将会替你处理这些,并把纹理保留在显卡以备再次使用。
在游戏机上,通常没有纹理高速缓存系统(除非你写一个)。在 PS2 上面,你最好是远离"一次纹理" 的方法。在 Xbox 上面, 这是不重要的,因为它本身没有图形内存(它是 UMA 体系结构),且所有的纹理无论如何始终保留在主存之中。
事实上,在今天的现代PC FPS 游戏中,试图通过AGP接口传送大量纹理是第二个最通常的瓶颈。最大的瓶颈是实际几何处理,它要使东西出现在它应该出现的地方。在如今的3D FPS 游戏中,最耗费时间的工作,显然是那些计算模型中每个顶点正确的世界位置的数学运算。如果你不把场景的纹理保持在预算之内,仅居其次的就是通过AGP接口传送大量的纹理了。然而,你确实有能力影响这些。 通过降低顶层的 MIP 级别(还记得系统在哪里不断地为你细分纹理吗?), 你就能够把系统正在尝试送到显卡的纹理大小减少一半。你的视觉质量会有所下降-- 尤其是在引人注目的电影片断中--但是你的帧速率上升了。这种方式对网络游戏尤其有帮助。实际上,Soldier of Fortune II和Jedi Knight II:
Outcast这两款游戏在设计时针对的显卡还不是市场上的大众主流显卡。为了以最大大小观看他们的纹理,你的3D 显卡至少需要有128MB的内存。这两种产品在思想上都是给未来设计的。
上面就是第 2 部份。在下面章节中,我们将介绍许多主题,包括内存管理,雾效果,深度测试,
抗锯齿,顶点着色,API等。
登录百度帐号推荐应用