网络棋牌游戏平台内核引擎是干啥用的,具体讲一下。。。

Zatacka X 0.1.6发布,多用户游戏引擎
Zatacka X 0.1.6 增加两种新的武器:Tron-mode 和 Disable;提供默认的玩家名称;可在游戏区域中显示边界;显示当前正在使用的武器。
Zatacka是一个在一个键盘上支持2-6个玩家的游戏引擎,从经典的DOS游戏――Achtung die Kurve 克隆而来。
通过两个键和鼠标按键,你必须侧击和其他玩家,当然墙壁。当一些球员死亡,生存得到一分。当只有一个球员还活着,该轮已完成。每场比赛有11发子弹。
本文地址:
转载请注明:文章转载自:开源中国社区 []
好文,顶一下
文章真差,踩一下
------分隔线----------------------------
把开源带在你的身边-精美linux小纪念品
初级应用->
高级应用-> |
编程开发->第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&硬件如何工作的理解等等。对於主机(游戏机)游戏来说,也需要相同类型的知识,但是至少对于主机,&你不必去尝试击中一个移动中的目标。&因为一台主机的硬件配置是固定的&&时间快照&,&和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&看见区域&AB&&&C&,&到更精致的&BSP(二叉空间分割)世界。&所有通过这些剔除测试的多边形被传递给多边形渲染器进行绘制。&
    ·&对於每一个被传递给渲染器的多边形,&渲染器依照局部数学&(&也就是模型动画)&和世界数学(相对于照相机的位置?)对多边形进行变换,并检查决定多边形是不是背对相机&(也就是远离照相机)。背面的多边形被丢弃。&非背面的多边形由渲染器根据发现的附近灯光照亮。然后渲染器要看多边形使用的纹理,并且确定&API/&图形卡正在使用那种纹理作为它的渲染基础。&在这里,多边形被送到渲染&API,然后再送给显卡。&
  很明显这有些过分简单化了,但你大概理解了。&下面的图表摘自Dave&Salvator's&3D&管线一文,可以给你多一些具体细节:&
  3D&管线
  -&高层的概观
   1.&应用程序/&场景
  ·场景/&几何数据库遍历
  ·对象的运动,观察相机的运动和瞄准
  ·对象模型的动画运动
  ·3D&世界内容的描述
  ·对象的可见性检查,包括可能的遮挡剔除
  ·细节层次的选择&(LOD)
  2.&几何
  ·变换&(旋转,平移,&缩放)
  ·从模型空间到世界空间的变换&(Direct3D)
  ·从世界空间到观察空间变换
  ·观察投影
  ·细节接受/&拒绝&剔除
  ·背面剔除&(也可以在后面的屏幕空间中做)
  ·透视分割&-&变换到裁剪空间
  ·裁剪
  ·变换到屏幕空间
  3.&三角形生成
  ·背面剔除&(&或者在光照计算之前的观察空间中完成)
  ·斜率/&角度计算
  ·扫瞄线变换
  4.&渲染&/&光栅化
  ·着色
  ·纹理
  ·Alpha&透明测试
  ·深度缓冲
  ·抗锯齿&(可选择的)
  ·显示
  通常你会把所有的多边形放到一些列表内,&然後根据纹理对这个列表排序(这样你只需要对显卡传送一次纹理,&而不是每个多边形都传送一次),&等等。在过去,会把多边形按照它们到相机的距离进行排序,首先绘制那些距离相机最远的多边形,&但现在由于&Z&缓冲的出现,这种方法就不是那么重要了。&当然那些透明的多边形要除外,它们要在所有的非半透明多边形绘制之后才能够绘制&,这样一来,所有在它们后面的多边形就能正确地在场景中显现出来。&当然,象那样,实际上你必须得从后到前地绘制那些多边形。&但时常在任何给定的&FPS&游戏场景中,&通常没有太多透明的多边形。&它可能看起来像有,但实际上与那些不透明的多边形相比,其比率是相当低的。&
  一旦应用程序将场景传递到&API,&API&就能利用硬件加速的变换和光照处理&(T&L),&这在如今的&3D&显卡中是很平常的事情。&这里不讨论涉及到的矩阵数学(参见Dave的&3D&管线导论),几何变换允许&3D&显卡按照你的尝试,根据相机在任何时间的位置和方向,在世界的正确角度和位置绘制多边形。&
  对于每个点或顶点都有大量的计算,&包括裁剪运算,决定任何给定的多边形实际上是否可见,在屏幕上完全不可见或部分可见。&光照运算,计算纹理色彩明亮程度,这取决于世界的灯光从什么角度如何投射到顶点上。&过去,处理器处理这些计算,但现在,当代图形硬件就能为你做这些事情,&这意谓着你的处理器可以去做其他的事情了。很明显这是件好事情&(tm)&,由于不能指望市面上所有的&3D&显卡板上都有T&&&L,&所以无论如何你自己将必须写所有的这些例程&(再一次从游戏开发者角度来说)。&你将在本文各处的不同段落看到&&好事情&(&tm)&&这个词汇。&我认为,这些特征为使游戏看起来更好作出了非常有用的贡献。&毫不令人吃惊,你也将会看见它的对立面;你猜到了,那就是“坏事情&(tm)”。&我正在尝试争取这些词汇的版权,&你要使用他们就得支付一笔小小的费用哟。
曲面片(高次表面)
  除了三角形,曲面片的使用现在正变得更普遍。&因为他们能用数学表达式来描述几何&(&通常涉及某种曲线的几何形体)&,而不仅仅只是列出大量的多边形以及在游戏世界中的位置,&所以曲面片&(&高次表面的另一个名称)&非常好。&这样,你实际上就能够动态地根据方程式来建立(&和变形&)多边形网格,&并决定你实际想要从曲面片上看到的多边形数量。&因此,举例来说,你可以描述一个管道,&然后在世界中就可以有这种管道的许多样例。&在一些房间中,&你已经显示了&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等。
第3部份:&内存使用,特效和API
关于内存使用的思考
  让我们想一想,在今天实际上是如何使用3D&显卡内存的以及在将来又会如何使用。&如今绝大多数3D显卡处理32位像素颜色,8位红色,&8位蓝色,8&位绿色,和&8&位透明度。这些组合的红,蓝和绿256个色度,可以组成&16。7&百万种颜色--&那是你我可以在一个监视器上看见的所有颜色。&
  那么,游戏设计大师John&Carmack&为什么要求&64&位颜色分辨率呢?&如果我们看不出区别,又有什么意义呢?&意义是:&比如说,&有十几个灯光照射模型上的点,颜色颜色各不相同。&我们取模型的最初颜色,然后计算一个灯光的照射,模型颜色值将改变。&然后我们计算另外的一个灯光,&模型颜色值进一步改变。&这里的问题是,因为颜色值只有8位,在计算了4个灯光之后,8位的颜色值将不足以给我们最后的颜色较好的分辨率和表现。分辨率的不足是由量化误差导致的,本质原因是由于位数不足引起的舍入误差。&
  你能很快地用尽位数,而且同样地,所有的颜色被清掉。每颜色16&或&32&位,你有一个更高分辨率,因此你能够反复着色以适当地表现最后的颜色。这样的颜色深度很快就能消耗大量的存储空间。我们也应提到整个显卡内存与纹理内存。这里所要说的是,每个3D&显卡实际只有有限的内存,而这些内存要存储前端和后端缓冲区,Z&缓冲区,还有所有的令人惊奇的纹理。最初的&Voodoo1&显卡只有2MB显存,后来&Riva&TNT提高到16MB显存。然后&GeForce&和&ATI&Rage有32MB显存,&现在一些&GeForce&2&到&4的显卡和&Radeons&带有&64MB&到128MB&的显存。&这为什么重要?&好吧,让我们看一些数字…
  比如你想让你的游戏看起来最好,所以你想要让它以32位屏幕,&分辨率和32位&Z-&缓冲跑起来。&好,屏幕上每个像素4个字节,外加每个像素4字节的Z-缓冲,因为都是每像素32位。我们有&个像素&–&也就是&1,310,720个像素。基于前端缓冲区和Z-缓冲区的字节数,这个数字乘以8,是&10,485,760字节。包括一个后端缓冲区,这样是&,&也就是&15,728,640&字节,&或&15MB。&在一个&16MB&显存的显卡上,就只给我们剩下1MB&来存储所有的纹理。&现在如果最初的纹理是真32&位或&4字节宽,那么我们每幀能在显卡上存储&1MB/4字节每像素&=&262,144个像素。这大约是4&个&256x256&的纹理页面。&
  很清楚,上述例子表明,旧的16MB&显卡没有现代游戏表现其绚丽画面所需要的足够内存。很明显,在它绘制画面的时候,我们每幀都必须重新把纹理装载到显卡。实际上,设计AGP总线的目的就是完成这个任务,不过,&AGP&还是要比&3D&掀卡的幀缓冲区慢,所以你会受到性能上的一些损失。很明显,如果纹理由32位降低到16位,你就能够通过AGP以较低的分辨率传送两倍数量的纹理。如果你的游戏以每个像素比较低的色彩分辨率跑,&那么就可以有更多的显示内存用来保存常用的纹理&(称为高速缓存纹理)&。&但实际上你永远不可能预知使用者将如何设置他们的系统。如果他们有一个在高分辨率和颜色深度跑的显卡,那么他们将会更可能那样设定他们的显卡。
  我们现在开始讲雾,它是某种视觉上的效果。如今绝大多数的引擎都能处理雾,&因为雾非常方便地让远处的世界淡出视野,所以当模型和场景地理越过观察体后平面进入视觉范围内时,你就不会看见它们突然从远处跳出来了。&也有一种称为体雾的技术。这种雾不是随物体离照相机的距离而定,它实际上是一个你能看见的真实对象,并且可以穿越它,从另外一侧出去&--&当你在穿越对象的时候,视觉上雾的可见程度随着变化。想象一下穿过云团&--&这是体雾的一个完美例子。体雾的一些好的实现例子是Quake&III一些关卡中的红色雾,或新的Rogue&Squadron&II&之&Lucas&Arts的&GameCube&版本。其中有一些是我曾经见过的最好的云--大约与你能看见的一样真实。
  在我们讨论雾化的时候,可能是简短介绍一下&Alpha&测试和纹理Alpha混合的好时机。当渲染器往屏幕上画一个特定像素时,假定它已经通过&Z-&缓冲测试&(在下面定义),我们可能最后做一些Alpha测试。我们可能发现为了显示像素后面的某些东西,像素需要透明绘制。这意味着我们必须取得像素的已有值,和我们新的像素值进行混和,并把混合结果的像素值放回原处。这称为读-修改-写操作,远比正常的像素写操作费时。&
  你可以用不同类型的混合,这些不同的效果被称为混合模式。直接Alpha混合只是把背景像素的一些百分比值加到新像素的相反百分比值上面。还有加法混合,将旧像素的一些百分比,和特定数量(而不是百分比)的新像素相加。&这样效果会更加鲜明。&(Kyle's&Lightsaber在&Jedi&Knight&II&中的效果)。
  每当厂商提供新的显卡时,我们可以得到硬件支持的更新更复杂的混合模式,从而制作出更多更眩目的效果。GF3+4和最近的Radeon显卡提供的像素操作,已经到了极限。
模板阴影与深度测试
  用模板产生阴影效果,事情就变得复杂而昂贵了。这里不讨论太多细节(可以写成一篇单独的文章了),其思想是,从光源视角绘制模型视图,然后用这个把多边形纹理形状产生或投射到受影响的物体表面。&
  实际上你是在视野中投射将会“落”在其他多边形上面的光体。最后你得到看似真实的光照,甚至带有视角在里面。因为要动态创建纹理,并对同一场景进行多遍绘制,所以这很昂贵。&
  你能用众多不同方法产生阴影,情形时常是这样一来,渲染质量与产生效果所需要的渲染工作成比例。有所谓的硬阴影或软阴影之分,而后者较好,因为它们更加准确地模仿阴影通常在真实世界的行为。&通常有一些被游戏开发者偏爱的“足够好”的方法。如要更多的了解阴影,请参考&Dave&Salvator的&3D&流水线一文。
  现在我们开始讨论深度测试,&深度测试丢弃隐藏的像素,过度绘制开始起作用。过度绘制非常简单&–&在一幀中,你数次绘制一个像素位置。它以3D场景中Z(深度)方向上存在的元素数量为基础,也被称为深度复杂度。如果你常常太多的过度绘制,&--&举例来说,&符咒的眩目视觉特效,就象Heretic&II,能让你的幀速率变得很糟糕。当屏幕上的一些人们彼此施放符咒时,Heretic&II设计的一些最初效果造成的情形是,他们在一幀中对屏幕上每个相同的像素画了40次!&不用说,这必须调整,尤其是软件渲染器,除了将游戏降低到象是滑雪表演外,它根本不能处理这样的负荷。深度测试是一种用来决定在相同的像素位置上哪些对象在其它对象前面的技术,这样我们就能够避免绘制那些隐藏的对象。&
  看着场景并想想你所看不见的。&换句话说,是什么在其他场景对象前面,或者隐藏了其他场景对象?&是深度测试作出的这个决定。&
  我将进一步解释深度深度如何帮助提高幀速率。想像一个很琐细的场景,大量的多边形&(或像素)位于彼此的后面,在渲染器获得他们之间没有一个快速的方法丢弃他们。对非Alpha混合的多边形分类排序(&在Z-&方向上),首先渲染离你最近的那些多边形,优先使用距离最近的像素填充屏幕。所以当你要渲染它们后面的像素(由Z或者深度测试决定)时,这些像素很快被丢弃,从而避免了混合步骤并节省了时间。如果你从后到前绘制,所有隐藏的对象将被完全绘制,然后又被其他对象完全重写覆盖。场景越复杂,这种情况就越糟糕,所以深度测试是个好东西。
  让我们快速的看一下抗锯齿。当渲染单个多边形时,3D&显卡仔细检查已经渲染的,并对新的多边形的边缘进行柔化,这样你就不会得到明显可见的锯齿形的像素边缘。两种技术方法之一通常被用来处理。&第一种方法是单个多边形层次,需要你从视野后面到前面渲染多边形,这样每个多边形都能和它后面的进行适当的混合。如果不按序进行渲染,最后你会看见各种奇怪的效果。在第二种方法中,使用比实际显示更大的分辩率来渲染整幅幀画面,然后在你缩小图像时,尖锐的锯齿形边缘就混合消失了。这第二种方法的结果不错,但因为显卡需要渲染比实际结果幀更多的像素,所以需要大量的内存资源和很高的内存带宽。
  多数新的显卡能很好地处理这些,但仍然有多种抗锯齿模式可以供你选择,因此你可以在性能和质量之间作出折衷。对於当今流行的各种不同抗锯齿技术的更详细讨论请参见Dave&Salvator&的3D&流水线一文。
顶点与像素着色
  在结束讨论渲染技术之前,我们快速的说一下顶点和像素着色,最近它们正引起很多关注。顶点着色是一种直接使用显卡硬件特征的方式,不使用API。举例来说,如果显卡支持硬件&T&&&L&,你可以用DirectX或OpenGL编程,并希望你的顶点通过&T&&&L&单元&(因为这完全由驱动程序处理,所以没有办法确信),或者你直接利用显卡硬件使用顶点着色。它们允许你根据显卡自身特征进行特别编码,你自己特殊的编码使用T&&&L&引擎,以及为了发挥你的最大优势,显卡必须提供的其他别的特征。&事实上,现在nVidia&和ATI&在他们大量的显卡上都提供了这个特征。&
  不幸的是,显卡之间表示顶点着色的方法并不一致。你不能象使用DirectX或者OpenGL&那样,为顶点着色编写一次代码就可以在任何显卡上运行,这可是个坏消息。然而,因为你直接和显卡硬件交流,它为快速渲染顶点着色可能生成的效果提供最大的承诺。(&如同创造很不错的特效&--&你能够使用顶点着色以API没有提供的方式影响事物)。事实上,顶点着色正在真的将3D&图形显示卡带回到游戏机的编码方式,直接存取硬件,最大限度利用系统的必须知识,而不是依靠API来为你做一切。对一些程序员来说,会对这种编码方式感到吃惊,但这是进步代价。
  进一步阐述,顶点着色是一些在顶点被送到显卡渲染之前计算和运行顶点效果程序或者例程。你可以在主CPU上面用软件来做这些事情,或者使用显卡上的顶点着色。&为动画模型变换网格是顶点程序的主选。
  像素着色是那些你写的例程,当绘制纹理时,这些例程就逐个像素被执行。你有效地用这些新的例程推翻了显卡硬件正常情况做的混合模式运算。这允许你做一些很不错的像素效果,&比如,使远处的纹理模糊,添加炮火烟雾,&产生水中的反射效果等。一旦&ATI&和&nVidia&能实际上就像素着色版本达成一致(&DX9's&新的高级阴影语言将会帮助促进这一目标),&我一点不惊讶DirectX&和OpenGL采用Glide的方式--&有帮助开始,&但最终不是把任何显卡发挥到极限的最好方法。我认为我会有兴趣观望将来。
最后(In&Closing...)
  最终,渲染器是游戏程序员最受评判的地方。在这个行业,视觉上的华丽非常重要,因此它为知道你正在做的买单。对于渲染器程序员,最坏的因素之一就是3D&显卡工业界变化的速度。一天,你正在尝试使透明图像正确地工作;第二天&nVidia&正在做顶点着色编程的展示。而且发展非常快,大致上,四年以前为那个时代的&3D&显卡写的代码现在已经过时了,需要全部重写。&甚至John&Carmack&这样描述过,他知道四年以前为充分发挥那个时期显卡的性能所写的不错的代码,如今很平凡&--&因此他产生了为每个新的id项目完全重写渲染器的欲望。Epic&的Tim&Sweeney赞同&--&这里是去年他给我的评论:&
  我们已经足足花费了9个月时间来更换所有的渲染代码。最初的&Unreal&被设计为软件渲染和后来扩展为硬件渲染。下一代引擎被设计为&GeForce&及更好的图形显示卡,且多边形吞吐量是Unreal&Tournament的100倍。&
  这需要全部替换渲染器。很幸运,该引擎模块化程度足够好,我们可以保持引擎的其余部分—编辑器,物理学,人工智能,网络--不改动,尽管我们一直在以许多方式改进这些部分。
  搭配长篇文章的短篇报导(Sidebar):API&--&祝福和诅咒
  那么什么是API?&它是应用程序编程接口,将不一致的后端用一致的前端呈现出来。举例来说,很大程度上每种3D显示卡的3D实现方式都有所差别。然而,他们全部都呈现一个一致的前端给最终使用者或者程序员,所以他们知道他们为X&3D显示卡写的代码将会在Y&3D显示卡上面有相同的结果。好吧,不管怎样理论上是那样。&大约在三年以前这可能是相当真实的陈述,但自那以后,在nVidia&公司的引领下,3D显卡行业的事情发生了变化。&
  如今在PC领域,除非你正计划建造自己的软件光栅引擎,使用CPU来绘制你所有的精灵,多边形和粒子&--&而且人们仍然在这样做。跟Unreal一样,Age&of&Empires&II:&Age&of&Kings有一个优秀的软件渲染器&–&否则你将使用两种可能的图形API,OpenGL或者&DirectX&之一。OpenGL是一种真正的跨平台API&(使用这种API写的软件可以在Linux,Windows和MacOS上运行。),&而且有多年的历史了,为人所熟知,但也开始慢慢地显示出它的古老。&大约在四年以前,定义OpenGL驱动特征集一直是所有显示卡厂商工作的方向。
  然而,一旦在目标达成以后,没有预先制定特征工作方向的路线图,这时候,所有的显卡开发商开始在特征集上分道扬镳,使用OpenGL扩展。
  3dfx&创造了T-&缓冲。&nVidia&努力寻求硬件变换和光照计算。Matrox努力获取凹凸贴图。等等。&我以前说过的一句话,&过去几年以来,3D显示卡领域的事情发生了变化。&委婉地说明了这一切。&
  无论如何,另一个可以选择的API是&DirectX。这受Microsoft公司控制,且在PC&和&Xbox&上被完美地支持。由于明显的原因,DirectX&没有Apple或者&Linux&版本。因为Microsoft控制着&DirectX,大体上它容易更好地集成在Windows里面。&
  OpenGL和DirectX之间的基本差别是前者由‘社区’拥有,而后者由Microsoft拥有。如果你想要&DirectX&为你的&3D&显示卡支持一个新的特征,那么你需要游说微软,希望采纳你的愿望,并等待新的&DirectX发行版本。对于OpenGL,由于显示卡制造商为3D显示卡提供驱动程序,你能够通过OpenGL扩展立即获得显示卡的新特征。这是好,但作为游戏开发者,当你为游戏编码的时候,你不能指望它们很普遍。它们可能让你的游戏速度提升50%,但你不能要求别人有一块GeForce&3&来跑你的游戏。好吧,你可以这么做,但如果你想来年还在这个行业的话,这是个相当愚蠢的主意。
  这是对这个问题极大的简单化,对我所有描述的也有各种例外情况,但这里一般的思想是很确实的。对于DirectX&,在任何既定时间你容易确切地知道你能从显示卡获得的特征,如果一个特征不能获得,DirectX&将会用软件模拟它(也不总是一件好事情,因为这样有时侯非常的慢,但那是另外一回事)。对于OpenGL,你可以更加贴近显示卡的特征,但代价是不能确定将会获得的准确特征。&
第4部份:&模型与动画,细节级别
角色建模与动画
  你的角色模型在屏幕上看起来怎么样,怎样容易创建它们,纹理,以及动画对于现代游戏试图完成的`消除不可信`因素来说至关重要。角色模型系统逐渐变得复杂起来,&包括较高的多边形数量模型,&和让模型在屏幕上移动的更好方式。
  如今你需要一个骨骼模型系统,有骨架和网格细节层次,单个顶点骨架的评估,骨架动画忽略,以及比赛中停留的角度忽略。而这些甚至还没有开始涉及一些你能做的很好的事情,像动画混合,骨架反向运动学(IK),和单个骨架限制,以及相片真实感的纹理。这个清单还能够继续列下去。但是真的,在用专业行话说了所有这些以后,我们在这里真正谈论的是什么呢?让我们看看。&
  让我们定义一个基于网格的系统和一个骨骼动画系统作为开始。在基于网格的系统,对于每一个动画幀,你要定义模型网格的每个点在世界中的位置。举例来说,你有一个包含200&个多边形的手的模型,有&300&个顶点(注意,在顶点和多边形之间通常并不是3个对1个的关系,因为大量多边形时常共享顶点&–&使用条形和扇形,你能大幅减少顶点数量)。如果动画有&10&幀,那么你就需要在内存中有300个顶点位置的数据。&总共有300&x&10&=&3000&顶点,每个顶点由x,y,z和颜色/alpha信息组成。你能看见这个增长起来是多么的快。Quake&I,II和&III&都使用了这种系统,这种系统确实有动态变形网格的能力,比如使裙子摆动,或者让头发飘动。
  相比之下,在骨骼动画系统,网格是由骨架组成的骨骼(&骨架是你运动的对象)。&网格顶点和骨架本身相关,所以它们在模型中的位置都是相对于骨架,而不是网格代表每个顶点在世界中的位置。因此,如果你移动骨架,组成多边形的顶点的位置也相应改变。这意谓着你只必须使骨骼运动,典型情况大约有&50&个左右的骨架—很明显极大地节省了内存。
骨骼动画附加的好处
  骨骼动画的另一个优点是能够根据影响顶点的一些骨架来分别“估价”&每个顶点。例如,双臂的骨架运动,肩,脖子而且甚至躯干都能在肩中影响网格。当你移动躯干的时候,网格就活像一个角色一样移动。总的效果是3D角色能够实现的动画更加流畅和可信,且需要更少的内存。每个人都赢了。&
  当然这里的缺点是,如果你想要使有机的东西运动且很好,比如说头发,或者披肩,为了让它看起来自然,你最后不得不在里面放置数量惊人的骨架,这会抬高一些处理时间。&
  基于骨骼的系统能带给你的一些其他事情是‘忽略’特定层次骨架的能力&--&说,&我不关心动画想要对这块骨架所做的事情,我想要让它指向世界中的一个特定点&。这很棒。你能让模型着眼于世界中的事件,或者使他们的脚在他们站着的地面保持水平。这一切非常微妙,但它可以帮助带给场景附加的真实感。
  在骨骼系统,你甚至可以指定&我需要把这个特别的动画用於模型的腿,而一个不同的携枪或射击动画在模型躯干上播放,且那家伙(角色)叫喊的不同动画效果在模型的头部播放&。非常妙。Ghoul2&(&在Soldier&of&Fortune&II:&Double&Helix&and&Jedi&Knight&I:&Outcast中使用了Raven的动画系统&)&拥有所有这些好东西,且特别被设计为允许程序员使用所有这些忽略能力。这对动画的节省像你一样难以相信。像你一样的动画上的这次救援不相信.&Raven有一个角色行走的动画和一个站立开火的动画,并在它同时行走和开火形下把这两个动画合并,而不是需要一个动画表示角色行走并开火。
More&Skeletons&in&the&Closet
  先前描述的效果可以通过具有层次的骨骼系统来完成。这是什么意思呢?意思是每块骨架实际上的位置相对于它的父亲,而不是每个骨架直接位于空间中的地方。这意谓着如果你移动父亲骨架,那么它所有的子孙骨架也跟着移动,在代码上不需要任何额外的努力。这是让你能够在任何骨架层次改变动画,而且通过骨骼其余部分向下传递的东西。&
  创建一个没有层次的骨骼系统是可能的&--&但那时你不能忽略一个骨架并且预期它工作。你所看到的只是身体上的一个骨架开始了新动画,除非你实现了某种‘向下传递信息’的系统,否则在该骨架下面的其它骨架保持原来的动画。首先由一个层次系统开始,你就自动地获得这些效果。&
  许多今天的动画系统中正开始出现一些比较新的特征,如动画混合,从一个正在播放的动画转变到另外一个动画需要经过一小段时间,而不是立即从一个动画突然转变到另外一个。举例来说,你有个角色在行走,然后他停了下来。你不是仅仅突然地转变动画,让他的腿和脚停在无效位置,而是一秒钟混合一半,这样脚似乎自然地移到了新的动画。不能够过高的评价这种效果&--&混合是一个微妙的事情,但如果正确的运用,它真的有些差别。
反向运动学
  反向运动学&(IK)&是被许多人们丢弃的一个专业术语,对它的真实含义没有多少概念。IK&是如今游戏里面一个相对比较新的系统。使用&IK&,程序员能够移动一只手,或一条腿,&模型的其余关节自动重新定位,因此模型被正确定向。而且有模型的关节新位置的其馀者他们自己,因此模型正确的被定向。比如,你将会说,&好,手&,&去拾起桌子上的那个杯子&并指出杯子在世界中的位置。手就会移动到那里,且它后面的身体会调节其自身以便双臂移动,身体适当弯曲,等等。
  也有和IK相反的事情,叫做前向运动学,本质上与&IK&工作的次序相反。想像一只手,手附着在手臂上,手臂附着在身体上。现在想像你重重地击中了身体。通常手臂像连迦般抽动,且手臂末梢的手随之振动。&IK&能够移动身体,并让其余的四肢自己以真实的方式移动。基本上它需要动画师设定每种工作的大量信息&--&像关节所能通过的运动范围,如果一块骨架前面的骨架移动,那么这块骨架将移动多少百分比,等等。
  和它现在一样,尽管很好,它是一个很大的处理问题,不用它你可以有不同的动画组合而脱身。值得注意的是,真正的&IK&解决办法需要一个层次骨骼系统而不是一个模型空间系统&--&否则它们都耗时太多以致无法恰当地计算每个骨架。
LOD几何系统
  最后,我们应当快速讨论一下与缩放模型几何复杂度相关的细节级别(LOD)系统(与讨论MIP映射时使用的LOD相对照)。假定如今绝大多数PC游戏支持的处理器速度的巨大范围,以及你可能渲染的任何给定可视场景的动态性质(在屏幕上有一个角色还是12个?),&你通常需要一些系统来处理这样的情况,比如,当系统接近极限试图同时在屏幕上绘制出12个角色,每个角色有3,000个多边形,并维持现实的幀速率。&LOD&被设计来协助这样的情景中。最基本的情况,它是在任何给定时间动态地改变你在屏幕上绘制的角色的多边形数量的能力。面对现实吧,当一个角色走远,也许只有十个屏幕像素高度,你真的不需要3000个多边形来渲染这个角色&--&或许300个就够了,而且你很难分辨出差别。&
  一些&LOD&系统将会需要你建立模型的多个版本,而且他们将会依靠模型离观察者的接近程度来改变屏幕上的LOD级别,&以及多少个多边形正被同时显示。更加复杂的系统实际上将会动态地减少屏幕上的多边形数量,在任何给定时间,任何给定的角色,动态地&--&Messiah和Sacrifice包括了这种风格的技术,尽管在CPU方面并不便宜。你必须确信,与首先简单地渲染整个事物相比,你的&LOD&系统没有花较多的时间计算出要渲染那些多边形(或不渲染)。&任一方式都将会工作,由于如今我们试图要在屏幕上绘制的多边形数量,这是件非常必要的事情。注意,&DX9&将会支持硬件执行的自适应几何缩放(tessellation)。
  归结起来是,得到一个运动流畅,其表现和移动在视觉上可信,屏幕上看起来逼真的模型。流畅的动画时常是通过手工建造动画和运动捕捉动画的组合得到。有时你仅仅手工建立了一个给定的动画&--&当你在为一个模型做一些你在现实生活中不能做到的事情的动画时,&你倾向于这样做&--&举例来说,你确实不能向后弯腰,或像Mortal&Kombat&4中的Lui&Kang那样在行进的脚踏车上踢腿,通常运动捕捉这时候就出局了!&通常运动捕捉动画&--&实际上视频捕捉活生生的演员贯穿于你想在屏幕上所看到的动画&--&是得到逼真的东西的方式。真实感的东西能使一款普通游戏看起来很棒,而且能掩饰许多事情。比如&NFL&Blitz,屏幕上的模型大约有&200&个多边形。它们在静止站立时看起来可怕的斑驳,一旦这些模型跑动起来它们就有快速流畅的动画,模型自身的许多丑陋消失了。眼睛容易看见的是&'逼真的'&动画而不是模型自身的结构。&一个不错的模型设计师能够掩饰大多数模型缺陷。
  我希望这些带给你对模型和动画问题的洞察力。在第五部份中,我们将会更加深入3D世界的建造,讨论一些物理,运动和效果系统的东西。
第5部分:&物理,运动,效果
  常常在建立一个含有任何3D成分的游戏时,你最终要试图建立一个将会在里面产生游戏动作的3D环境。&不知怎么的游戏开发者提供了一个建立这种环境的方,它容易修改,有效率,有较低的多边形数量,对于游戏既容易渲染又容易运用物理学。很简单,对吗?当做这个的时候我用左手在做什么?当做这的时候&,&我对我的左手做什么?&是的。不错。&
  虽然那里有许多3D结构程序,从CAD/CAM程序到3D&Studio&Max,建造游戏世界是不同于建造内部或外部世界的模型的尴尬。你有三角形数量问题&--&任何给定的渲染器一次只能渲染这么多的多边形,这对于天才的关卡设计师来说永远都不够。不知这些,你也只能每个关卡存储预定数量的多边形,所以即使你的渲染器能够在视野中处理250,000个多边形,即使你只能在合理数量的空间中存储500,000个多边形,那么取决于你怎么处理它,最后你的关卡价值像两个房间那么小。不好。&
  任何方法,开发者需要提出一个创作工具&--&最好足够灵活,允许游戏引擎需要的各种事物&–&比如,在世界中放置对象,在进入游戏以前对关卡的适当预览,以及准确的光照预览。在他们花三个小时预先处理关卡来产生一个&'引擎可消化的'&格式之前&,&这些能力允许游戏开发者看到关卡将在游戏中看起来怎么样。&开发者需要关于关卡,多边形数量,网格数量等等的相应数据。&他们需要一个合宜而友好的方式能够让世界有纹理背景图,容易存取多边形数量缩减工具,如此等等。这个清单可以继续列下去。&
  在先前已经存在的工具中找到这个功能是可能的。许多开发者使用Max或者Maya建造他们的关卡,&但即使3D&Max需要对它的功能有一些任务特定的扩展来有效率地完成关卡建造工作。甚至可能使用关卡建造工具,像QERadient(见下图),而且把它的输出重新处理成你的引擎能够解释的格式。
不能看见它?&别烦扰…
  回想一下我们在第一部分讨论的BSP&(二叉空间分割)&树,你也可能听说过潜在可视集合(PVS)这个术语正被四处谈论。两者都有相同的目标,不去探究涉及到的繁杂的数学,它是一种把世界分解为你能从世界任何给定位置看见的墙壁的最小子集的方式。在实现时,它们仅仅返回你能看见的那些,而不是那些隐藏在可能被遮挡的墙壁后面的。你能想象出这给软件渲染器带来的好处,渲染的每个像素(可能是这样的情形)极为重要。它们也按从后到前的顺序返回那些墙壁,在渲染时这是很方便的,因为你能够在渲染次序中确定一个对象的实际位置。&
  大体而言,BSP&树最近正不受欢迎,由于它们的一些古怪,而且因为我们从当今3D显示卡获得的像素吞吐量,再加上Z缓冲像素测试,BSP&常常成了一个多余的过程。它们在计算出你在世界的确切位置和正在你周围的几何物体方面是便利的,但常常有比BSP树更好而且更直观的方式来存储这些信息。&
  潜在可视集像它听上去一样非常好。它是这么一个方法,在任何给定时间,给定你在世界的位置,它决定世界的哪些表面,哪些对象实际上可以看得见。这时常用来在渲染之前剔除对象,也剔除它们来减少AI和动画处理。毕竟,如果你实际上不能看见它们,为什么还要费脑筋处理呢。多半这真的是不重要的,如果一个非玩家角色(NPC)正在播放动画,或者甚至在运行它的AI思考。
游戏物理学
  既然我们已经在内存中得到了世界的结构,我们必须防止我们的角色从里面掉落出去,并处理地板,斜坡,墙壁,门,以及移动平台。加之,我们必须正确地处理地心引力,速度变化,惯性,和放置在世界里面的其它对象的碰撞。这被看作是游戏物理学。而且在我们进一步深入讨论之前,我想现在就在这里消除一个神话。任何时候你在世界中看见物理,或者任何人在一个复杂的游戏环境中宣称“真实的物理”,很好,它是BS。超过80%的建造一个有效率游戏物理系统的精力花在简化用来处理世界中对象的真实方程式上面。甚至那时,你时常忽略什么是‘真实的’,并创造一些‘有趣的’东西,毕竟,这是目标所在。
  经常地游戏者将会忽视真实世界的牛顿物理学,并扮演他们自己的,更有趣的真实版本。例如,在QuakeII里面,你能够立即从0加速到35MPH,并快速停下来。没有摩擦力,而且斜坡不提供真实斜坡提供的相同类型的重力问题。身体没有它们应该的作用在所有关节上的地心引力&--&你看不见身体像真实生活中那样倒在桌子上面或者边缘&--&而且地心引力它本身甚至可能是可变的。&面对现实吧,在真正的世界中,空间中的飞船不像二战飞行战斗员在它们的表面操作那样实行。在空中,全部是力和反作用力,力在重量点周围作用,等等。不像&X-Wing中的Luke&Skywalker那样啸叫。尽管那样做更加有趣!&
  作为游戏开发者来说,无论我们做什么,我们需要能够检测墙壁,检测地板,在世界中处理和其他对象的碰撞。这些是现代游戏引擎的必备&–&我们决定对它们进一步要做的取决于我们和我们的游戏需要。
  如今绝大多数的游戏引擎建造有某种效果产生器,这允许我们表现出有洞察力的游戏者期盼的所有可爱的吸引眼球的东西。然而,效果系统幕后所进行的东西能够急剧影响幀速率,所以这是我们需要特别关心的地方。如今我们有很棒的3D显示卡,我们能够传送大量的三角形给它们,而且他们仍然要求更多的三角形。并不总是那样。&在Heretic&II,使用它的可爱的软件渲染模式,由于他们漂亮的符咒效果,Raven遇到了相当严重的过度绘制问题。回想当你在屏幕上绘制相同的像素超过一次时,过度绘制就发生了。当你有许多效果正在进行,按其性质你有许多三角形,多个三角形可能相互堆叠在彼此上面。结果是你有许多重复绘制的像素。加上Alpha,这意味着在重新绘制之前你必须读取旧像素并和新的像素混合,这会消耗更多的CPU时间。&
  Heretic&II的一些效果能说明这点,我们在一幀里对整个屏幕重复绘制了四十遍。很惊讶,是吗?因此他们在效果系统里面实现了一个系统采样在过去30幀的幀速率,如果速度开始减慢,它就自动地缩减任何给定效果绘制的三角形数量。这样使主要工作完成了,幀速率保持住了,但一些效果看上去很丑陋。&
  无论如何,因为如今绝大多数效果倾向使用大量很小的粒子模拟火和烟等等,结果你在效果代码里面每幀要处理许多的三角形。你必须把它们从一幀移动到下一幀,决定它们是否完成了,甚至还要在它们身上运用一些物理学以便让它们在地板上面适当的反弹。这在PC上面都是相当昂贵的,因此甚至现在你必须对你所能够做的有一些实际限制。举例来说,用一个像素粒子产生火的效果可能会很好,但当你这么做的时候就别期望在屏幕上做更多别的事情。&
  粒子被定义为拥有它们自己的世界位置和速度的非常小的可绘制的物体。它们不同于有方向的精灵,大的粒子使用这些精灵&--&比如喷出的一团团烟雾。它们面向照相机自动而典型地旋转,缩放,改变它们的透明级别,因此它们能够随着时间淡出。我们容易看到大量的粒子,但我们却限制精灵的数量—尽管两者之间的真正不同如今正在模糊。将来,特别是在&DX9&和更加高级的图形硬件表面以后,我们可能看到更多的人们使用过程shader来产生跟粒子系统相似或者更好的效果,创造非常棒的动画效果。&
  当谈论效果系统时,你可能听说过‘图原’这个词。一个图原是你的效果系统将处理的效果的最低级别的物理表现。更进一步解释,一个三角形是一个图原。那是绝大多数引擎最终在底层绘制的&--&大量的三角形。当你沿着系统向上时,你对图原的定义随着变化。比如说,顶层的游戏程序员不想考虑处理个别的三角形。他仅仅想说,&这个效果在这里发生&&并让系统以一种黑盒方式处理它。因此对于他来说,一个效果图原就是‘让我们在世界的这点持续这么长时间用这样的引力产生一束粒子’。在效果系统内部,它可能认为一个效果图原是它那时正在产生的每个单独的效果,像一组遵循同样的物理学规
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:12253次
排名:千里之外
转载:80篇
(2)(2)(1)(2)(1)(1)(5)(40)(30)

我要回帖

更多关于 古剑奇谭是不是游戏 的文章

 

随机推荐