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

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


第3部份: 内存使用特效和API


有关内存使用研究
  让我们想在今天实际上是如何使用3D 显卡内存以及在将来又会如何使用 如今绝大多数3D显卡处理32位像素颜色8位红色 8位蓝色8 位绿色和 8 位透明度这些组合蓝和绿256个色度可以组成 167 百万种颜色-- 那是你我可以在个监视器上看见所有颜色  

  那么游戏设计大师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位屏幕 1280x1024分辨率和32位 Z- 缓冲跑起来屏幕上每个像素4个字节外加每个像素4字节Z-缓冲都是每像素32位我们有1280x1024 个像素 – 也就是 1310720个像素基于前端缓冲区和Z-缓冲区字节数这个数字乘以8是 10485760字节包括个后端缓冲区这样是 1280x1024x12 也就是 15728640 字节 或 15MB个 16MB 显存显卡上就只给我们剩下1MB 来存储所有纹理 现在如果最初纹理是真32 位或 4字节宽那么我们每幀能在显卡上存储 1MB/4字节每像素 = 262144个像素这大约是4 个 256x256 纹理页面  

  很清楚上述例子表明16MB 显卡没有现代游戏表现其绚丽画面所需要足够内存很明显在它绘制画面时候我们每幀都必须重新把纹理装载到显卡实际上设计AGP总线就是完成这个任务不过 AGP 还是要比 3D 掀卡幀缓冲区慢所以你会受到性能上些损失很明显如果纹理由32位降低到16位你就能够通过AGP以较低分辨率传送两倍数量纹理如果你游戏以每个像素比较低色彩分辨率跑 那么就可以有更多显示内存用来保存常用纹理 (称为高速缓存Cache纹理) 但实际上你永远不可能预知使用者将如何设置他们系统如果他们有个在高分辨率和颜色深度跑显卡那么他们将会更可能那样设定他们显卡



  我们现在开始讲雾,它是某种视觉上效果如今绝大多数引擎都能处理雾 雾非常方便地让远处世界淡出视野所以当模型和场景地理越过观察体后平面进入视觉范围内时你就不会看见它们突然从远处跳出来了 也有种称为体雾技术这种雾不是随物体离照相机距离而定,它实际上是个你能看见真实对象并且可以穿越它从另外侧出去 -- 当你在穿越对象时候视觉上雾可见程度随着变化想象下穿过云团 -- 这是体雾个完美例子体雾些好实现例子是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次! 不用说这必须调整尤其是软件Software渲染器除了将游戏降低到象是滑雪表演外它根本不能处理这样负荷深度测试是种用来决定在相同像素位置上哪些对象在其它对象前面技术这样我们就能够避免绘制那些隐藏对象  

  看着场景并想想你所看不见 换句话说是什么在其他场景对象前面,或者隐藏了其他场景对象? 是深度测试作出这个决定  

  我将进步解释深度深度如何帮助提高幀速率想像个很琐细场景大量多边形 (或像素)位于彼此后面在渲染器获得他们的间没有个快速思路方法丢弃他们对非Alpha混合多边形分类排序( 在Z- 方向上)首先渲染离你最近那些多边形优先使用距离最近像素填充屏幕所以当你要渲染它们后面像素(由Z或者深度测试决定)时这些像素很快被丢弃从而避免了混合步骤并节省了时间如果你从后到前绘制所有隐藏对象将被完全绘制然后又被其他对象完全重写覆盖场景越复杂这种情况就越糟糕所以深度测试是个好东西


抗锯齿
  让我们快速下抗锯齿当渲染单个多边形时3D 显卡仔细检查已经渲染并对新多边形边缘进行柔化这样你就不会得到明显可见锯齿形像素边缘两种技术思路方法的通常被用来处理种思路方法是单个多边形层次需要你从视野后面到前面渲染多边形这样每个多边形都能和它后面进行适当混合如果不按序进行渲染最后你会看见各种奇怪效果在第 2种思路方法中使用比实际显示更大分辩率来渲染整幅幀画面然后在你缩小图像时尖锐锯齿形边缘就混合消失了这第 2种思路方法结果不错显卡需要渲染比实际结果幀更多像素所以需要大量内存资源和很高内存带宽

  多数新显卡能很好地处理这些但仍然有多种抗锯齿模式可以供你选择因此你可以在性能和质量的间作出折衷对於当今流行各种区别抗锯齿技术更详细讨论请参见Dave Salvator 3D 流水线


顶点和像素着色
  在结束讨论渲染技术的前我们快速下顶点和像素着色最近它们正引起很多关注顶点着色是种直接使用显卡硬件特征方式不使用API举例来说如果显卡支持硬件 T & L 你可以用DirectX或OpenGL编程并希望你顶点通过 T & L 单元 (这完全由驱动处理所以没有办法确信)或者你直接利用显卡硬件使用顶点着色它们允许你根据显卡自身特征进行特别编码你自己特殊编码使用T & L 引擎以及为了发挥你最大优势显卡必须提供其他别特征 事实上现在nVidia 和ATI 在他们大量显卡上都提供了这个特征  

  不幸显卡的间表示顶点着色思路方法并不你不能象使用DirectX或者OpenGL 那样为顶点着色编写次代码就可以在任何显卡上运行这可是个坏消息然而你直接和显卡硬件交流它为快速渲染顶点着色可能生成效果提供最大承诺( 如同创造很不错特效 -- 你能够使用顶点着色以API没有提供方式影响事物)事实上顶点着色正在真将3D 图形显示卡带回到游戏机编码方式直接存取硬件最大限度利用系统必须知识而不是依靠API来为你做员来说会对这种编码方式感到吃惊但这是进步代价

  进步阐述顶点着色是些在顶点被送到显卡渲染的前计算和运行顶点效果或者例程你可以在主CPU上面用软件Software来做这些事情或者使用显卡上顶点着色 为动画模型变换网格是顶点主选

  像素着色是那些你写例程当绘制纹理时这些例程就逐个像素被执行你有效地用这些新例程推翻了显卡硬件正常情况做混合模式运算这允许你做些很不错像素效果 比如使远处纹理模糊添加炮火烟雾, 产生水中反射效果等旦 ATI 和 nVidia 能实际上就像素着色版本达成致( DX9's 新高级阴影语言将会帮助促进这目标), 我点不惊讶DirectX 和OpenGL采用Glide方式-- 有帮助开始, 但最终不是把任何显卡发挥到极限最好思路方法我认为我会有兴趣观望将来


最后(In Closing...)
  最终渲染器是游戏员最受评判地方在这个行业视觉上华丽非常重要因此它为知道你正在做买单对于渲染器最坏原因的就是3D 显卡工业界变化速度你正在尝试使透明图像正确地工作;第 2天 nVidia 正在做顶点着色编程展示而且发展非常快大致上 4年以前为那个时代 3D 显卡写代码现在已经过时了需要全部重写 甚至John Carmack 这样描述过他知道 4年以前为充分发挥那个时期显卡性能所写不错代码如今很平凡 -- 因此他产生了为每个新id项目完全重写渲染器欲望Epic Tim Sweeney赞同 -- 这里是去年他给我评论:  

  我们已经足足花费了9个月时间来更换所有渲染代码最初 Unreal 被设计为软件Software渲染和后来扩展为硬件渲染代引擎被设计为 GeForce 及更好图形显示卡且多边形吞吐量是Unreal Tournament100倍  

  这需要全部替换渲染器很幸运该引擎模块化程度足够好我们可以保持引擎其余部分—编辑器物理学人工智能网络--不改动尽管我们直在以许多方式改进这些部分

  搭配长篇文章短篇报导(Sidebar):API -- 祝福和诅咒
  那么什么是API? 它是应用编程接口,将不后端用前端呈现出来举例来说很大程度上每种3D显示卡3D实现方式都有所差别然而他们全部都呈现前端给最终使用者或者所以他们知道他们为X 3D显示卡写代码将会在Y 3D显示卡上面有相同结果好吧不管怎样理论上是那样 大约在 3年以前这可能是相当真实陈述但自那以后在nVidia 公司引领下3D显卡行业事情发生了变化  

  如今在PC领域除非你正计划建造自己软件Software光栅引擎使用CPU来绘制你所有精灵多边形和粒子 -- 而且人们仍然在这样做跟UnrealAge of Empires II: Age of Kings有个优秀软件Software渲染器 – 否则你将使用两种可能图形APIOpenGL或者 DirectX 的OpenGL是种真正跨平台API (使用这种API写软件Software可以在LinuxWindows和MacOS上运行) 而且有多年历史了为人所熟知但也开始慢慢地显示出它古老 大约在 4年以前定义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 将会用软件Software模拟它(也不总是件好事情这样有时侯非常但那是另外回事)对于OpenGL你可以更加贴近显示卡特征,但代价是不能确定将会获得准确特征
Tags:  游戏搜索引擎 游戏引擎启动异常 什么是游戏引擎 游戏引擎

延伸阅读

最新评论

发表评论