国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php框架 > 框架设计 > 探寻次时代渲染 - CryEngine2

探寻次时代渲染 - CryEngine2

来源:程序员人生   发布时间:2016-11-24 08:37:36 阅读次数:4032次

Advanced Real-Time Rendering in 3D Graphics and Games Course – SIGGRAPH 2007

探访次时期渲染 - CryEngine2

作者:Martin Mittring

   Crytek 游戏公司

翻译:潘曦

(译文里的pancy:XXX)为译者注)

              (本系列文章由pancy12138编写,转载请注明出处:http://blog.csdn.net/pancy12138)

1:来自于获奖游戏”孤岛危机”的1张截图,它的发布为渲染界开辟了下1个时期。

 

 

2:来自于行将到来的最新的孤岛危机的截图。

 

 

摘要

在这篇文章中,我们其实不具体探讨某1种特定的算法。而是尝试去寻觅德国公司Crytek使用的1些能在1起发挥出更好的效果的渲染算法。(pancy:这篇论文所提到的大部份算法都是以往就提出的,Crytek所做的工作是从众多的图形算法中找到最合适使用的算法,将他们经过1些改变,让他们能够更容易实现,相互融会并利用于真实的图形工业当中。这对现代实时渲染技术的发展意义很大

我们认为这些信息对所有希望能够实现与Crytek公司相似的渲染效果的人员来讲都是有用的,由于常常我们在算法实现的时候所遭受到的瓶颈正是在某1渲染效果的基础上实现1个渲染效果的时候(pancy:也就是我们在同时用多种渲染算法渲染场景的时候,出现的问题和bug也最多),我们同时简明的介绍了1些你可能会斟酌使用的可以用于替换那些方法的途径。我们并没有把图形方面所做的所有工作完全的进行讲授,由于在这篇文章中我们挑选了读者们所感兴趣并且我们能够拿得出手的领域的拓展技术进行讲授。Crytek的开发选取了图形学社区最近几年来最具先进意义的理论研究,并且结合了1些新的思想以使得这些先进的理论能够有效的映照到现今的图形硬件当中。

介绍

Crytek studios所开发的1个技术出色的第1人称射击游戏”孤岛危机”在其1经发布便广受好评,“孤岛危机”的出现提高了所有同类型游戏的制作门坎,当我们公司成功开发了“孤岛危机I”以后,1个很自然的想法是使用这目前的的引擎来经过很少的改变制作1个它的续作。因此续作会几近使用在第1作中用到的相同的引擎。固然,这是1个最简单且获利最高的决定,但是我们相信这类想法必定会限制我们最初的目标-为游戏赋予更好的技术和艺术。因此我们决定去设计1个全新的次时期渲染引擎并且想法提高新引擎的设计和架构,除新添加的1些特性,新的游戏“孤岛危机II”将会继承1代的游戏风格,不过新的游戏取得各个方面的极大范围的效果提升。游戏的1切将会变得更加庞大和优秀。而我们所设计的新的游戏引擎 CryEngine2则会让我们的梦想成真。(pancy:这篇文章的讲授重点,尽人皆知的著名次时期引擎CryEngine,introduction写的简直英气冲天)

在我们浏览了设计文档和开过了1个紧张的审议会议以后,我们所有的设计师,程序员,和艺术家达讨论出了1组新引擎需要达成的以下目标:

游戏需要包括3种不同的环境:

 

3:丛林中的天堂

具有大量的模型对象,3维高度图,海洋,广阔的视野,来自于1个方向光源的环境光。

 

4:外星人的室内场景。

具有许多点光源,整体偏暗,区域划分,几何体相互遮挡,体积雾效果

 

5:冰雪环境

冰材料层,地面的次表面散射

完成所有的3个场景是1项极具挑战性的工作,主要的优化难点在于他们具有完全不同的特点。

1.避免触发恐怖谷效应的电影级渲染pancy:恐怖谷效应,当虚拟人物的真实程度将要到达真实人类水平而未到达时会出现1个“恐怖谷”此时人类会对这类虚拟人物感到最大的恐惧和厌烦,认真实程度真正到达真实人类水平的时候才会让人类对其的好感回升):渲染质量越接近视频质量,则观众就需要对游戏投入越少的忍受。

 

 

2.动态光线与阴影:提早算好的光照数据是许多算法提高渲染质量和性能的1个关键因素,而由于这些算法常常具有静态依赖的特性,所以我们不使用这些算法而是使用动态的光影算法。

 

 

3.支持多个GPU与CPU协同工作:多线程加多个图形卡协作开发是1项很复杂的任务,由于我们大多时候必须要为了更好地协同而牺牲其他的配置。

 

 

4.场景大小需要21km*21km的游戏范围:我们希望做到这1点,但是终究的生产,流水线,和世界的持久性收益其实不值得我们做这些努力,终究我们实现了多个4km*4km的游戏范围。

 

 

5.显卡指令从shader model2.0升级至shader model4.0(Directx10):虽然看上去使用shader model2.0作为开发指令是1个最方便的选择,但是这类做法会使得我们在directx10下使用最新的图形卡和图形驱动进行开发遭到阻碍。

 

 

6.高动态暴光(HDR):我们在“孤岛危机I”中使用HDR取得了非常好的效果。为了更真实的视觉效果,我们希望设计的游戏不受低动态的亮度差所限制。

 

 

7.动态环境(可能会被break):这是1项很酷炫的技术,不过非常难以实现。

 

 

8.在开发渲染引擎的时候同时开发游戏:这将迫使我们总是在1些正在使用的状态中进行编码,这对1个小型的工程是比较简单的,但是当工程变得巨大的时候这项工作将变得极具挑战性。

 

我们的概念艺术家创作了许多概念图来肯定了游戏最初的雏形。但是为了让大家感遭到终究的渲染效果,我们通过外包公司 Blur3 studio制作了1份宣扬我们设计理念的视频。这有助于让我们到达我们希望到达的外观和感受。

 

6:Blur3制造的用于为Crysis公司的引擎设计的概念视频的1帧截图

概括:

在这篇文章的余下部份,我们会先讨论CryEngine2所使用的新的着色框架,这个领域对我们的大范围场景来讲是1个极大的挑战。以后,我们会介绍我们在实现直接照明与非直接照明效果时所使用的解决方法(包括1些设计思路),我们使用专门的算法将不同的光照从总问题中隔离出来讨论,并且用更加先进的方法来解决它。在做完这些处理后,我们先从阴影的角度来处理直接光照(由于阴影在不同复杂度的shader中都可以很轻易的完成)。间接光照我们可以用环境光遮蔽技术来进行摹拟,通过简单的令光线变暗来代表环境光遮蔽的贡献。最后,我们涵盖了各种算法去解决各个层次的细节问题。固然,本篇文章只会包括我们引擎在渲染方面所做的工作,但是这仍然会给予读者读我们全部系统的1个不错的”品味”,并且运行我们在这些选定的领域做足够深入的发掘。

着色器与着色技术:

1.cryengine1的历史回顾

“孤岛危机I”中,我们支持的最低等级的显卡装备是NVIDIA GeForce 2系列。这也意味着我们不但可使用顶点着色器和像素着色器,还能共同支持固定管线T&L函数与寄存器管线(通过提早运行pixel shader解决方案来进行纹理混合)。为了到达这个目标和支持更复杂的材质,我们的Directx和Opengl的shader脚本有了更复杂的规则。在“孤岛危机I”以后,我们希望提高前作的质量并且重构之前的系统。首先我们移除所有固定管线的支持,并让语法更贴近于[Microsoft07]中所描写的FX语法格式。在项目的晚期,我们为项目加入了1个基于接über-shader的1些新的渲染路径。这基本上是由1个使用CG或HLSL语言书写的包括了很多#ifdef的1个pixel shader和1个vertexshader组成的渲染路径,这使得开发变得简单而快捷,由于我们完全的避免了手动优化的步骤。初期的shader编译器还不能够总是创建出到达人类手工优化的汇编指令,但是在shadermodel2.0的显卡上已修缮了很多。über-shader渲染路径的内置变化非常的多,所以将他们1次全部编译时不可能的,我们在开发进程中发现在编译的时候有明显的延迟(当我们不能不编译shader的时候),但是我们希望能够在建立游戏的时候具有1个已预编译好的shader存储器。我们会在1开始暂停我们的游戏在Nvida或Ati硬件装备上的运行直到我们的缓存器读完所有的信息。更多细节可以参考我们的第1款引擎的[Wenzel05]章节。

2.cryengine2

我们决定减少需求的数量以使得新的引擎更加简洁,因此我们移除opengl的支持和固定管线的支持,这使得我们可以将shder的格式更接近于FX格式,shder的开发和学习也变得更加方便和简洁(pancy:FX格式是微软为directx实现的1种shder管理格式,cryengine要想在opengl和固定管线中也是用这类格式是比较困难的,移除这两个支持极大的统1了shader格式)。我们面临的另外一个待解决的问题是shder的组合太过庞大,我们重建了全部shader系统,围棋添加了1个shader需求列表缓冲器。这1列表的数据通过网络从公司的所有机器上取得,并且我们在夜间对缓存中的shader进行编译工作。但是编译时间依然显得太长了,因此我们决定通过以下操作来减少shader的组合个数。

1.动态分支。

2.减少组合并且接受更少的功能。

3.减少组合并减少1定的性能。

4.多通道分离。

我们通过使用散布式的shader编译器的屡次迭代,在1个小时内完成了所有shader的编译。

3.格式法线贴图

ATI[ARI04]提出的3DcTM纹理格式允许将法线贴图的每一个像素点通过1个高质量且只有1点点额外shader(重建z缓冲区)的代价紧缩至1个字节,未紧缩的法线贴图1般使用4个字节来存储1个像素(法线的xyz存储在RGB份量中,另外一个字节的份量会被填充并浪费),在我们的新引擎中,我们决定在纹理的加载进程中不做紧缩操作,而是在我们的纹理处理工具中进行处理,在纹理处理工具中为其创建mip levels和紧缩。这类方法使得我们通过简单的预处理得到了快捷的加载速度。对那些不支持3Dctm的硬件,我们会在加载的时候将这类格式转化为DXT5格式,这类格式与之前的格式非常的相似因此转换是很方便的。当视频质量规格较低的时候纹理转换带来的质量上的损失是可以接受的。而且即使是较为古老的NVIDA显卡的驱动也是有3DcTM纹理摹拟的,所以我们不需要在这个方面做过量的关心(这类摹拟是没有转换损失的,相应的代价是每一个像素需要2个字节的存储空间)。

4.逐像素景深

使用提早的深度缓冲测试可以减少像素着色的代价,由于大部份像素都可以在深度测试的时候被剔除掉,这样就这些像素就不需要在pixel shader里面被履行。由于我们希望使用更复杂的pixel shader进行像素着色。我们的渲染管线从1开始就使用提早的深度缓冲区测试。如果这样做的话,我们就需要添加更多的draw call(pancy:我们通常使用的z-test是在 pixel/fragment shader 以后的,如果希望在此之前进行测试则需要先把场景写入到深度缓冲区1遍,这样就最少多了1次draw call)。而在很多效果器(pancy: effect是FX格式所定义的单位,包括1整套渲染路径,此处翻译为效果器)当中,我们还希望能够使用到场景的深度信息。这样我们就需要将深度缓冲区的输出绑定到纹理资源上以备使用。1开始我们使用R16G16的纹理格式,缘由是这类格式能够被所有的硬件所支持并且16位的大小也足以实现我们想要的质量。最初我们是使用双通道的纹理资源但是终究我们优化了这个方法。在ATI的显卡上,我们使用R16纹理格式以节省1些内存和带宽的消耗。我们意想到在1些硬件装备上R16G16格式要比R32格式的速度要慢,所以当显卡不支持R16格式的时候,我们采取R32格式去替换它。固然,直接访问深度缓冲区是1种更好的选择,由于这样我们不需要额外的内存,提早的深度测试会变得更加快捷(在1些硬件上不写入色彩到纹理可以提升两倍的速度)。因此在最后我们根据机器的支持程度来使用R16,R32乃至是默许的深度缓冲区。深度数据被用于在延迟渲染中的1些渲染技能当中(pancy: CryEngine在这篇论文里面所使用到的很多算法都是需要深度重建的,比shadowmap和ssao,这些算法的特点就是通过屏幕空间的深度还原原始的点坐标的3维信息来大大减少算法在像素着色器上的复杂度)。通过1个MAD操作和1个3份量插值机,我们完全有希望根据深度信息重建这个点的原始3维信息。固然,如果需要到达浮点型的精度,还是最好根据摄像机的位置或邻近点的位置进行3维重建,如果我们在pixel shader里面使用了24位或16位的浮点数据的话,那末这类3维重建的方式就变得很重要了。通过偏移所有的模型对象和光源,我们很容易让视察者接近坐标原点(0,0,0)。如果不做这个操作的话,贴图和动画效果会出现很多跳动和闪烁。我们将景深效果利用于逐像素的场景效果其当中,终究效果和全局雾效,体积雾,和软深度缓存粒子的效果很相像。

阴影模板的创建也借助场景的深度来减少draw call个数,对水面的摹拟,我们也能够使用深度数据去柔化水面效果,并沿着海岸逐步增强。1些后处理效果例如运动模糊,景深摹拟和边沿模糊也一样会用到各个像素的深度信息。这些算法的细节记录在[Wenzel07]。

5.世界空间着色

“孤岛危机I”当中,我们将视点和光源转换到了切线空间(根据物体的表面方向),由于所有传入pixel shader的数据都是定义于切线空间的,所以很自然的着色算法也是在切线空间进行的。而这也使得我们在程序中能够运行的光照数量受制于shder内部插值器数量的限制。为了解决这1问题,我们决定将着色模型从且切线空间着色转换成世界空间着色(事实上,我们在运行世界空间着色的时候做了1些偏移以减少浮点类型顶点的精度丢失)。这类着色方法在实现cube map反射算法的时候一样需要用到。因此着色代码会变得更加统1和高质量,并且世界空间也不会像切线空间1样容易扭曲。1些影响因素例如光源的位置可以在pixel shader中设置为常量,这样就没必要在所有的模型对象中都进行更新。固然如果我们只是用1个光源或单1的shader进行着色的话,这类做法在额外的像素计算上付出的代价就会显得比较高。(pancy:这里提到的方法相当于我们现在所说的延迟渲染框架,延迟渲染的好处是剔除所有我们眼睛看不到的顶点使很多个光源的性能大大提升,如果场景只有1个光源的话那就完全丧失了其优势。)

阴影与环境光遮蔽

1.CryEngine1的阴影摹拟

在我们的第1作“孤岛危机I”中,我们使用了shadow map技术根据1个全局太阳光为每一个模型结构构建了1个阳光下的阴影。在当时我们就已遇到了1个典型的shadow map贴图混淆的质量问题,但是在当时这项技术已是1个最好的选择了。斟酌到性能方面的问题,我们将植被的阴影做了预先的计算,但是由于内存的限制我们只能使用极为模糊的贴图来摹拟植被。在高端配置的硬件装备上,我们乃至为植被也加上了实时的shadow map算法,但是将这些阴影与与计算阴影相互结合的时候依然有很多缺点。对点光源,我们采取了模板阴影算法来计算阴影,而这对点光源来讲是简洁而先进的阴影算法。CPU上的蒙皮操作(pancy:蒙皮操作是指骨骼动画里根据父子关系存储的骨骼坐标系对人体或动物的表面顶点进行变换的进程。如今所有的蒙皮操作都是在GPU上进行的,如果在CPU上进行的话不但会拖慢程序的帧率,还会大量消耗CPU)允许我们将阴影轮廓从CPU里抽出,然后在GPU里面渲染模板阴影体。很明显,这类做法要求我们具有更精致的模型对象,并且需要额外的CPU开消来做蒙皮工作和将蒙皮结果上传至GPU,同时,我们还得准备更多的内存来存储轮廓数据。这使得我们几近没法预测终究的性能特点(pancy:CPU过度使用将使得性能预测不可用,由于此时有可能CPU成为渲染瓶颈以致于不能根据GPU运算能力和问题范围预测和优化算法复杂度)。并且,这类做法还会使得我们没法使用alpha混合和阴影投射技术。这也就意味着这项技术乃至不能用于渲染对热带岛屿非常重要的棕榈树(图7)。

 

7:“孤岛危机”截屏:注意与计算的阴影与实时计算的阴影柔和的混合在了1起

在开发的进程中,我们希望对所有的室内阴影使用模板阴影体技术,但是,这类技术产生的多光源下的硬阴影的外观和性能都不能使人满意,这使得我们希望能寻觅其它的技术来解决室内阴影问题。1个解决方案是将阴影存储在光照贴图当中,光照贴图能够在不管多少个光源的照耀下保证阴影的柔和性。但是不幸的是光照贴图存储的是着色以后的光照结果,这是1个单纯的RGB纹理,因此我们没法在其上面实现法线贴图。我们解决了这项问题并且为我们的解决方案起名叫做Dot3Lightmaps[Mittring04],在我们的解决方案中,我们在光照贴图中存储了1个平均后的切线空间中的光线方向,1个平均后的光照色彩和1个在纯洁的环境光和纯洁的方向光之间插值以后的混合值。这个操作使得我们能够很快地计算出各个静态光源对软阴影效果的贡献。但是这类阴影贴图难以和实时阴影混合,在“孤岛危机”发布以后,我们实验了1种简单的修改,并为之命名为遮蔽映照(Occlusion maps),这类做法的主要概念是使用1个0⑴的值作为阴影掩码来代表几何体对纹理元素的遮蔽概率。我们在光照贴图当中存储了来自于多个光源的阴影掩码并且通常所用的4通道纹理允许1个像素点存储4个光源的掩码信息。通过这类方式,我们实现了1种高质量的软阴影并且成功的计算出了每个漫反射光和镜面反射光对其的贡献值,同时,光照的色彩和强度还是可以灵活改变的。我们1直保持所有光源的信息是分开的,这样才能保证他们和其余类型的阴影完善的融会。

2.CryEngine2的计划

我们认为是时候统逐一下全部阴影系统了。由于上面提到的1些问题,我们决定放弃模板阴影算法(pancy:shadow voluem就这么没了deth)。而shadow map总是可以提供高质量的软阴影并且可以方便的调控性能和质量,因此我们选择这项技术来实现我们的阴影。但是这项技术只能用于直接光照下的阴影摹拟,而如果没有斟酌到间接光照的话,我们的游戏就很难到达电影级别的渲染效果。因此,我们计划使用这个方法来解决直接光照阴影,而使用另外一个方法来解决间接光照阴影。

3.直接光照

对直接光照,我们决定只使用shadowmap技术(将几何体对象在视野方向的的深度存储在1个2D纹应当中)而取消所有的模板阴影的使用。

<1>:动态遮蔽贴图:

为了能够有效的处理静态光源的位置,我们希望做1些新的探讨。通过对室内几何体进行1些独特的展开,shadowmap的查询结果可以被存储在遮蔽贴图中被动态的进行更新。动态遮蔽贴图的思想史很好的,并且确切起到了1定的作用。但是由于阴影总是会产生混淆毛病,所以现在我们不单单是阴影,连几何体的展开也出现了混淆。以往用于改良这个问题的纹理拉伸技术有些过于古老了,并且它也不能避免掉所有的纹理拼接缝隙。由于我们仍然需要为动态的物体计算shadowmap,所以我们决定最大程度的加大通用的shadowmap并且下降遮蔽贴图的大小(pancy:shadowmap算法虽然非常简洁,但是问题也很多,常见的包括阴影锯齿(也就是这里提到的混淆效果),阴影瑕疵等等,这是由于shadowmap在1定程度上属于光栅类算(shadowmap被存储于纹理并且在使用的时候被反投影来寻觅深度),因此其效果取决于视截体的大小和阴影贴图的分辨率

<2>:shadow map与屏幕空间随机纹理查询:

平面shadow mapping由于混淆现象而变得非常糟并且会产生非常严重的锯齿边沿(见第1张印象图)PCF滤波算法(百分比滤波)可以减轻这个问题,但是它需要进行更多的采样,斟酌到当初的硬件运算水平,这类滤波算法仅仅能够在NVIDA6代或7代的图形加速卡上运转,并且仿真速度被大大的拖慢了。而在更先进的ATI的显卡上,我们可使用Fetch4函数(在[Isidoro06]中定义)。为了代替使用更多的采样实现PCF算法,我们还设计了1种随机像素查找的方法以减少采样数量来到达相似的阴影效果。固然,这会带来1点图象的噪声,噪声(或躁点)在任何影视图象上都会有,所以我们可以根据采样数量来灵活的控制和调剂运算性能和质量。我们的灵感来源于光线追踪的软阴影算法。并且这项算法已利用于GPU上的shadowmap创建。(具体的提升和优化shadowmap质量的细节请浏览[Uralsky05]与[Isidoro06])

盘状散布的随机偏移可以被利用于2D纹理的查询。当我们使用1个较大的偏移量的时候,平坦的表面的阴影渲染质量将会由于其表面被随机纹理肯定的方向而提高,1个3D的图形例如说球体将会消耗更多的渲染资源,但他应归属于偏移的柔化问题。

如果想要得到没有太多噪声的可接受结果,我们就需要更多的对阴影图进行采样。因此,采样次数与随机算法就能够根据需求的质量和效力不同来进行选择。我们尝试使用了两种方法产生圆盘状随机点,1个是对各粒子进行随机的进行旋转[Isidoro06],另外一个是使用1个简单的像素着色器。

 

8:不同质量的shadowmap样例:从左至右顺次是,无PCF,PCF,8次采样,8次采样加blur,PCF加8次采样,PCF加8次采样加blur。

第1种技术需要1个静态的2D随机点和1个存储着随机2维旋转矩阵的纹理。荣幸的是2位旋转矩阵比较小(2*2)可以被存储在4通道的纹理中,由于矩阵是正交的,所以还能够进行进1步的紧缩,但这不是必须的。负数的话可以用经常使用的“放缩偏移”方法进行转化(乘2减1)(pancy:x= x*2⑴可以将[0,1]转换到[⑴,1],由于通常的纹理只能存储0⑵55,因此shader中得到的色彩也是0⑴)或使用浮点纹理来存储(浮点纹理格式,不用0⑵55存储色彩而使用float存储色彩,最新的显卡都加入了这类扩大以方便的实现shadowmap,ssao,hdr等算法)。我们尝试了很多种不同的采样表,并且在图8中你可以看到利用这些采样来摹拟软阴影的效果是不错的。对1个圆形的随机盘状数据或许你希望将其完全填充,但是我们并没有填充其里脸部分的数据由于他们对采样来讲很少被用到。这类算法效果的瑕疵已很难被发觉了,但是为了更正确的结果,我们仍希望在算法上做1些改进。

1个更简单的获得采样点的方法是将1个或两个2D纹理上的随机正采样点进行简单的变换。第1个点可以放在中间(mx,my)然后其他的4个点将根据随机向量(x,y)放在中心点的周围:

(mx,   my)

(mx + x,my+y)

(mx - y ,my+x)

(mx - x ,my -y)

(mx + y,my -x)

这类做法使得我们可以构造出更多的采样点,固然我们发现这类做法只是能够提升那些低端显卡的材质渲染的速度(由于只有在低端显卡上我们才需要斟酌限制采样个数)。

这两种方法都允许我们调剂采样点的大小来实现软阴影。为了得到正确的结果,这个点的大小取决于投影距离和光照半径,固然这通常都是很容易近似计算的,最初我们采取64*64的纹理来1:1的映照屏幕像素(图9)。

                                     

                          9:1个随机采样点纹理样例。

这个随机纹理是经过精心制作以体现其随机性:在很高维度上都不可辨认出其特点细节。创建1个随机纹理图是最直接的方法,我们还可以手动生成1张特点易于辨认的纹理然后我们就可以够通过1个简易的算法来寻觅1些可以用于交换的相邻点,1个好的交换方式可以提高纹理的随机性频率(这个计算结果来自于对差异值的总结搜集(pancy:大概是用类似于我们计算方差的方法来判断纹理的随机程度如何))。固然,直接创建1张高随机频率的随机纹理是1个更好的选择。我们描写这个方法是由于这项技术更合适我们的目的。

 

影视级的效果其实不意味着我们要实现静态的效果,所以我们有可能将噪点进行运动并且希望这么做能够在采样率比较低的时候借助运动来隐藏这些噪点。不幸的是我们终究得到的结果就像是1个新的工艺品1般,帧率变得很低而且不稳定。那些没有动画的静态场景的噪点还能够差能人意,而随着摄像机的运动,1些随机纹理的静态特点所酿成的噪声开始出现在屏幕上。

<3>:shadow map与光照空间随机纹理查询:

荣幸的是我们找到了1个很好的办法来解决这个问题,我们在世界空间的太阳光照方向上创建了1个mip-map映照的噪声纹理以代替之前的屏幕空间噪声纹理,在中远距离上的渲染结果与之前是相似的,但是由于使用的双线性插值所以近处的阴影边沿变得扭曲而不再有噪声点了。这个视觉效果看上去比之前强了很多,特别是植物和植被,那些很难描写具体阴影形状的模型。

<4>:阴影掩码纹理:

我们将阴影的查找从我们的渲染管线中分离了出来,这样就能够避免遭到shader mode2.0的最大指令数的限制,减少shder的组合个数和允许多个阴影进行混合。我们通过查询平铺空间纹理取得了1个8位的阴影贴图,并称之为“阴影掩码”由于1张普通的纹理有4个通道32位作为渲染目标,所以1张4通道的纹理可以将4个灯光的阴影掩码存储在1个像素点里。

 

 

10:1个使用随机查找的阴影样例。左上:没有抖动,1次采样。右上:屏幕空间噪声,8次采样。左下:世界空间噪声,8次采样。右下:世界空间噪声,调剂后的8次采样


11:1个给定场景的阴影掩码纹理样例:左图:通过1个太阳光(视作1个阴影投射)和两个阴影投射光源。右图:来自于3个光源的阴影模板纹理的RGB显示

 

12:1个给定场景的阴影掩码纹理的样例,RGB通道代表3个独立光源的阴影掩码。

在渲染管线中,我们将这个纹理进行绑定并且立即根据这个纹理渲染出所有的光照和环境光效果。固然,我们除RGB通道外,还可以将帧缓冲区的alpha通道1并使用,但是这样我们就需要更多的pass(pancy:每一个渲染算法的1趟渲染称为1个pass,1般高级的殊效都是经过好几个pass共同渲染的结果)和draw call(pancy:每次调用图形api的draw操作称为1次draw call,在当年drawcall的数量会极大的影响程序的效力,因此1般都会严格控制到几百个左右,不过最新的硬件和api已在这个问题上做了很大的修缮,Directx12乃至宣称10万drawcall都不会影响到渲染效力)。对不透明的物体和仅仅需要alpha测试的物体(pancy:与alpha混合不同,alpha测试是直接扣除alpha通道不符合要求的像素点,1般来讲如果1个点只需要alpha测试意味着这个点不属于需要进行半透明混合的点,多半是全透明或用于某些算法的预计算)阴影模板可以得到非常好的效果,但是对那些需要进行alpha混合的几何体来讲这类算法起不到任何作用(pancy:现今流行的大部份屏幕空间的算法呢最大的问题就是很难处理半透明物体,像延迟渲染等都有这个问题,1旦物体需要进行alpha混合则这些算法就很难起到作用)。所有的不透明物体都可以被记录在深度缓冲区当中,但是需要进行alpha混合的点是不能够记录在深度缓存区当中的。因此,我们需要在着色器中为半透明的物体建立1张阴影法线贴图索引。

4.直接光照下的阴影贴图

“孤岛危机I”当中,我们仅仅使用了很少的阴影投射对象,并且每一个被投射的对象都有1个独立的shadowmap。当阴影投射的对象变得更多的时候,我们认为应当将这些阴影数据统1到1个shadowmap当中。在光照方向使用1个简单的平行投影就能够能够轻易的得到1个shadow

Map,但是这样会使得靠近视察者的阴影贴图分辨率非常的低,出现块状的阴影。如果我们更改参数,例如生成1个透视投影矩阵将靠近视察者的阴影贴图分辨率提升。但这也会出现1些问题。我们还尝试了梯形shadow map(TSM)([MT04])和透视shadowmap(PSM)([SD02])。

我们在使用级联shadowmap(CSM)的时候获得了较大的成功,这类算法通过对视野所在区域进行屡次投影得到了许多张不同范围的相同分辨率的shadowmap。每个投影的影象像素范围都包括于他前面的那个(pancy:更大的)投影所在的世界范围的像素区域内。这项技术得到了较好的结果,但是同时也浪费了1些纹理存储空间,主要是由于这些投影结果只是粗略的包括到了视察者前面的1些区域。为了找到适合的可划分的视截体(随着阴影区域大小的必须距离的减少而减少),每个shadowmap都需要包括1个划分,划分越远则视截体就能够包括越大的世界空间,当1个shadowmap视截体恰好完全的包括1个划分的时候,比他更小的shadowmap就应当被舍弃掉。如果使用以往的技术,我们已知道当摄像机进行旋转和平移的时候会出现阴影混淆。而在使用PSM和TSM的时候我们也没能解决这个问题,但是我们使用CSM加上我们的1些改进则解决了这个问题。我们只是更改了每一个shadowmap像素的投影方式就得到了1个非常清晰的阴影结果。

5.延迟阴影模板的建立

初始化阴影模板的创建需要渲染所有的可见几何体,这将会使用到更多的draw call。我们使用延迟技术将阴影模板的额建立从几何体渲染中分离了出来。我们先根据我们用提早z缓冲渲染的深度纹理进行1次全屏渲染pass,这次渲染使用1个简单的像素着色器(根据深度数据获得shadow map查询结果)。并且此次渲染不需要各个点在世界空间的坐标。正如前面所说的,我们使用了多张shadow map,这使得我们用于创建阴影掩码的着色器需要定义所有的像素点,以肯定每一个像素的阴影映照到了正确的纹理。为每个纹理添加索引可使用directx10的纹理数组功能或在1个大的纹理资源中进行偏移寻址。通过使用模板缓冲区,我们能够单独处理各个划分并且简化了像素着色器。修改后的技术运行速度变得更快了,由于像素着色器不需要再做复杂的操作。并且算法还屏蔽了那些不需要计算阴影的离视点较远的场景。

6.展开点光源的shadow map

通常点光源的shadow map都需要1张cube map贴图来进行深度索引。但是硬件PCF优化其实不能利用于cube map类型的纹理上面,由于这类纹理很难控制和管理其所占的存储空间。我们将cube map通过在模板缓存上的6次采样展开成6张阴影纹理贴图,这与我们在CSM中所做的操作很相似。这样我们就将点光源类型的阴影问题转换成了聚光灯类型的阴影问题。这使得代码更加的统1和易于保护并且减少了shader的组合。

7.方差shadow map算法(VSM)

对地形,我们最初希望先提早算好纹理的起始和结束角度,并且还试图实时的更新1张遮蔽映照纹理的增量。但是地形上的1些几何体总是出现1些问题。对那些大的物体,在不同的地形中需要适应不同的阴影。我们尝试使用我们的法线阴影贴图技术,这项技术统1了阴影外观,但是却致使了阴影的柔和度不足。我们还尝试使用更大范围的简单随机纹理进行索引,但是这使得噪声变得更加严重。在这里我们尝试使用方差shadowmap技术[DL06],而这项技术的终究效果非常的不错。当多个阴影贴图相互遮盖的时候方差阴影贴图的缺点就很明显了。但是对地形模型来讲这类情况是很少产生的。

 

 

13:使用VSM渲染场景的1个样例。上图:未使用方差阴影贴图(注意有硬法线阴影)。下图:使用了方差阴影贴图(注意两种阴影的结合)。

间接光照

1.3D Transport Sampler

在第1部份我们已计划设计1个叫做“3D transport sampler”的工具,这个工具可以将全局的光照数据分配到多个机器上(斟酌到性能缘由)。

光子映照([jensen01])是1种被大家所认可的计算全局光照的不错的方法。我们决定采取这类方法摹拟全局光照,由于它可以简便的统1到系统中,并且快速的得到较好的效果。

 

14:1个光源的实时环境光。

光子映照最早被利用于创建1个简单的光照映照。这项技术在我们过去的光线映照中实现的很简单,并且仅仅将相邻的3角形连接起来并只使用了1个简单的平面方程。这致使我们填充到多重纹理中的结果出现了很多2D的小块。同时当我们将算法用于更加精细的模型的时候纹理的使用效力开始显得很低,并且在纹理的边界拓展的时候出现了很多细小的中断(pancy:wrap,纹理拓展,1般来讲纹理采样UV的范围是[0,1],如果模型的UV超过了这个值就需要进行纹理拓展,具体的拓展方式根据利用而定,常见的有重复寻址和最外边寻址等)。因此我们更改了纹理的拓展方式,使用模型的纹理拓展UV作为基础并且只在我们需要的地方做拓展定义。这样的话负责美工的艺术家就能够对精细的模型的技术细节做更多且更适合的操控和修缮。我们本想将结果存储在Dot3lightmaps(前面已做过介绍)但是我们希望尝试用更好的方式来提升渲染质量。这个方法的主要思路是存储4个方向的光对表面的贡献。类似的技术曾被用于“半条命II”(pancy:CS吧??)但是他们只存储了3个方向的光。明显更多的数据将会带来更好的渲染效果。这些数据运行我们进行高质量的逐像素渲染,并且如果不追究细节的话可以和实时阴影较好的结合。但是,由于巨大的存储量和缓慢的运算速度,我们终究还是放弃了这类方式。其实我们最初的想法只是存储每一个像素的光照贴图系数和其余的每一个顶点的信息。将这些信息结合存储顶点连接关系的图形数据结构,我们好似有可能实现动态间接光照的。低频的光照份量可以存储在各个顶点结构中,高频的份量例如锋利的角落等可以存储在屏幕空间像素当(pancy:顶点结构数量与几何体有关,屏幕空间像素数量与光栅化有关,看开头还以为cryengine想挑战人类极限加入光子映照......结果居然是放弃了...弃了.....了)。由于开发时间是很珍贵的,所以我们终究还是放弃了这个想法。

2.实时环境光映照(RAM)

作为替换,我们选择了1个更简单的解决方案,只需要为每一个像素存储1个环境光遮挡值标量。

环境光遮蔽值([ZIK98,Landis02])可以根据各个方向的发射光线来进行计算。这些光线有些是光子映照中没有使用到的。我们在着色器中使用这些必要的信息进行重建:存储了遮蔽值的像素,与表面方向相干的光源位置,光照色彩及表面法向量。我们终究得到了1个粗略的近似环境光,但是人眼对环境光其实不是很敏感,所以终究效果还是不错的。为了能支持法线贴图技术,我们需要对光照方向进行平均化,由于我们没法取得能较好的和法线贴图表面配合的光照方向。即使使用这类方法,法线贴图仍然能够被发觉到,而着色效果也很大的依赖于光照角度。因此我们让环境光的亮度,色彩和衰减系数都是可以调控的以便设计人员设计出更好的终究外观。当斟酌到入口效果的时候,这项技术可以进行扩大以使得太阳光可以混合多个其他光线。对更大的室外环境,为每一个表面计算1个RAM是不可行的,因此我们决定使用其他的技术。

3.屏幕空间环境光遮蔽(SSAO)

我们的1个很有创意的程序员想出了1个不错的方法。这类方法使用我们之前已计算出来的z缓冲数据来计算出1种环境光遮蔽。(pancy:我就想知道那个有创意的程序员叫啥名字......1个不谨慎成了SSAO之父啊!1个不谨慎推动了实时渲染的改革.....)这个方法非常的诱人,由于所有的不透明对象都可以在没有特殊处理的情况下得到环境光遮蔽,并且不需要额外的内存开消。同时,很多渲染部份的的复杂处理也都可以顺手移除。虽然我们现有的解决方案已工作的不错了,但是我们还是希望能够计算出所有种类的动态环境光。这类方法基于屏幕像素与采样像素进行简单的深度比较在物体的周围得到1个由遮蔽因子决定的轮廓。而这类环境光遮蔽的效果仅仅决定于这个点对周围光线的的接收程度。经过量次的迭代和优化,我们得到了1种意想不到的效果,我们将其称为“屏幕空间环境光遮蔽”(SSAO)。我们通过1次对全屏幕像素履行的pass来计算环境光遮蔽效果。我们还尝试将这类效果同时利用于环境光,漫反射和镜面反射,但是终究发现他只是对环境光摹拟效果最好。最大的缘由多是这类算法使得渲染的真实化遭到了影响,这也是我们未来的优化目标。

为了减少采样次数我们将采样点跟改成像素附近点的采样,初始的样本散布于1个以源点为中心的球体表面。然后通过1个随机的3D平面将这些采样点反射到随机的采样位置。

                    n:来自于纹理的归1化的随机像素向量。

                    i:  来自于球面的随机采样点

             Float3 reflect(float3 i,float3 n){return i⑵*dot(i,n)*n}

 

反射是很容易计算的,并且将随机平面法向量存储在纹理中是非常足够的。

 

15:使用屏幕空间环境光遮蔽只计算环境光得到的效果(注意在远距离处,遮蔽使得色彩非常的暗)

 

 

16:场景A使用特殊材质使ssao可视化的1个样例(左:使用ssao,右:未使用ssao)

 

17:场景B使用特殊材质使ssao可视化的1个样例(左:使用ssao,右:未使用ssao)

 

18:场景A使用特殊材质使ssao可视化的1个样例(左:使用ssao,右:未使用ssao)

多细节层次(LOD)

1.现状

当渲染的复杂度不容易控制的时候,层次细节技术(LOD)是非常重要的,很多游戏通常使用雾化效果对视野做了很大的限制,乃至有时候依托层次设计来强行遮蔽掉远处的信息。这也就是为何大多数游戏都是以室内环境为主导的,但是在“孤岛危机I”中,我们希望能够展现非常远处的风景和许多细节,同时不限制玩家的视角和运动位置。因此,我们保持了“孤岛危机”中的视角范围,但是我们为模型增加了不同层次的高质量细节描写。质量的提升意味着我们需要使用更加复杂的着色器,更加高质量的纹理。全新的纹理类型(例如地表纹理)和更多的网格点。由于我们还希望使用z缓冲前置技术和实时阴影效果,所以我们需要对每一个模型对象付出更多的代价。而过量的drawcall使得CPU负担增加,不过这在Directx10上有所改良。因此在“孤岛危机”中,我们可以很轻易的在美工创作的不同细节程度的模型中进行切换。固然,我们还为植被添加了1些欺骗的技术以改良他们在游戏中的运行效力(pancy:估计是billboard或cross billboard之类的公告板技术 )但是这不属于本章的讨论范围。

“孤岛危机”中,我们打算使用1个基于移动顶点的平滑的LOD过度。但是这类技术常常对模型创建带来很多限制。而如果没有这类限制的话模型常常能够快速而高效的建立出来。特别是那些需要alpha测试或alpha混合的植被模型。这使得有时候我们的模型来不及建立LOD转换而不能不在显示demo的时候直接取消低LOD等级的部份。用于演示demo的机器具有非常高的硬件配置因此低等级的LOD其实不能增强运算速度。而低等级的LOD所援用的范围通常在屏幕上只占很少的1部份,所以总的像素消耗是很少的。使用大量的LOD还有可能适得其反,由于这项技术其实不容易让不同层级的对象完善融会,并且我们还得消耗更多的draw call。

2.融会技术

我们的1个程序员终究想到了1个基于在z缓冲前置事前进行模型融会的方式来柔化LOD的转换。而在我们以后的额渲染进程中只需要打开z缓冲前置。固然这其实不是1个完全正确的方法由于物体的表面有可能会具有相同的深度值,这样使用add类型的alpha混合(pancy:add型混合 finalpixel = sourcepixel + destpixel)使得这些点取得了两倍的亮度。但是由于每一个物体第1次渲染的目标帧缓冲区不允许混合,所以这类情况只有在以后的pass才有可能产生。不过我们将所有的光照合并到了1个pass当中,因此这类情况产生的几率就非常小了。融会后的纹理属于屏幕空间的1个投影,然后我们随机从纹理中收集1个值与每一个物体的变换值进行融会,并在以后使用简单的alpha测试来排除不符合要求的点。我们在最新的图形硬件卡上采取了较为新颖的alpha2coverage(A2C)技术(pancy:alphatocoverage技术,通常alpha测试由于简单地根据alpha排除不透明点使得边界锯齿严重,为了到达类似于alpha混合的效果,DIrectx10使用了1种叫A2C的方法来消除1些alpha测试留下的锯齿)和全屏抗锯齿技术(FSAA)在亚像素级别上进行优化。即使不使用FSAA技术,如果我们使用到我们的边沿模糊后处理效果,融会的瑕疵也不宜被发觉到。最初我们只是根据模型与视点的距离来进行状态的过度。当时处于过渡期的模型的渲染速度和质量都变得很差,因此我们决定在过渡期隐藏这些模型。这也就是为何我们为模型过度添加了1小段代码以让其在定义的1段时间内完成。我们不单单对变换的3D对象使用融会技术,还将这项技术用于隐藏远处的模型和隐藏过渡期间的模型已到达欺骗视觉的效果。

3.水面的LOD技术

海面或大范围的水面通常具有特殊的属性,因此可使用特殊的渲染算法进行渲染。最初我们在“孤岛危机”中实现的水面是1个随着玩家运动的简单网格,由像素着色器,反射效果和透明度决定了水面的视觉效果。但是,我们希望具有真实的3D波浪,固然不是基于物理摹拟,而是1种便宜的解决方案。我们尝试通过使用基于FFT(pancy:快速傅里叶变换)的水波仿真([Jensen01a], [Tessendorf04]).要想取得3D的波浪就必须要进行必要的顶点操作,而我们以往使用的网格模型明显是不能够做这样的操作的。

4.立方水域

前面提到的FFT仅仅适能够输出海面的较小的1部份,因此我们必须将表面渲染很屡次才能取得想要的范围。不同的细节层次所使用的索引缓冲区不同,但是他们同享1个由FFT生成的顶点缓冲区(pancy:顶点缓冲区决定组成几何体的多边形的顶点位置,索引缓冲区决定了多边形的组织方式。)我们虽然同享了所有LOD的顶点缓冲区以节省内存,但是为了更好地渲染质量(pancy:也就是LOD中被认为不重要的几何体需要下降渲染质量)我们需要更好的向下采样方式。为了减少随距离而产生的混淆现象和限制低质量多边形的外观,对近处的点,我们淡化了其对远处顶点的扰动。并且大大限制了其对周围近处顶点的扰动(pancy:大概是很大程度上简化了液体之间的受力方式)。这类方法确切起到了作用但是很多美工建议我们还是再找1些更好的方法。

5.屏幕空间曲面细分

我们决定使用1些暴力的方法,这类方法很简单,但是很好的解决了问题。我们使用1个提早计算好的屏幕空间曲面细分4边形并且将所有的水面顶点投影到这张4边形上。这项操作必须严格保证z缓冲区的正确性,乃至我们还要裁剪掉所有地平面上面的顶点所产生的像素。为了能够使用FFT波浪摹拟数据来修改顶点的位置,我们需要建立1张顶点纹理索引,由于这项技术其实不能在硬件上实现(pancy:硬件曲面细分始于directx11,当时虽然有使用曲面细分摹拟水面的算法但是只能通过1些别的手段实现这项功能)

                       

                        2:屏幕空间曲面细分产生的波浪

线框中可以注意到的垂直线条是由于我们为了更好的日升顶点缓冲区性能所做的顶点分层。这个结果看上去让我们觉得终究成功的希望很大,但是屏幕边界上的顶点总是在阔别边界的位置,这是1个很严重的问题。固然,为缓冲区扩容,以包括哪些超越边界的顶点可以解决这个问题。不过衰减顶点的扰动的方法更合适,由于不但对屏幕边界影响其实不是很明显,并且还能最小化的增加额外本钱。

 

3:左:不做衰减顶点扰动的屏幕空间曲面细分(注意左侧界的部份没有被包括到水面)。右:衰减顶点扰动的屏幕空间曲面细分。

为了更好的提高性能,我们减少了顶点的细分程度,而即使我们使用比之前少很多的顶点,工程的质量依然是可接受的。取景角度的倾斜将使得渲染效果大大下降,这不是我们期望的结果。主要缘由是边沿衰减主要依赖于水面方向的摄像机,而不是真实的物理摹拟。因此我们不能不减少波动的幅度以解决这个问题。

6.摄像机对齐

剩余的1些历史遗留的锯齿混淆问题和物理运动学的问题困扰着我们的shader程序员。然后他花了1些时间找到了1个以下的解决方案:这类新的方法更之前1样使用了1个静态的网格。但是这个网格的投影从之前的单1角度转换成了简单的上下投影。全部网格由摄像机来进行移动,我们通过调剂摄像机的偏移量以使得摄像机面对方向所获的顶点数量最大化。要渲染地平线以上的顶点,我们就需要对网格的边沿进行显著的扩大。而这些顶点的曲面细分不再很关键由于对这类远距离定点,其受扰动的系数几近可以视为0。

      

204:摄像机对齐后的水面网格的线框:左:上下投影的摄像机对齐空间,右:从视察者角度观看的相机空间。

这类做法得到的效果要优于屏幕空间的做法,特别是在相机做微小的运动的时候更加的明显。除随距离的衰减,水波现在是与视察者位置无关的。因此现在使用CPU摹拟FFT物理运动是可行的。

 

21:左:摄像机对齐的结果。右:用于比较的屏幕空间曲面细分

总结

通过这次曲折的探究,我们不但找到了我们的下1代引擎的发展方向,还从中学到了很多的东西。为了找到,验证和比较不同的解决方案,学习的进程是必不可少的。在过去的说法中,这项工作可以被归类于研究工作。我们认为我们选取他人的研究成果最大的根据是质量,生产时间,性能和可扩大性。“孤岛危机II”,我们的新1代的游戏,是1个巨大的工程,为了掌控这项工程,时间是非常重要的。1个解决方案的性能与硬件息息相干(如CPU,GPU,内存),因此对不同的平台我们都可能要重新斟酌我们所使用的算法。目前的引擎对具有多个核心的CPU和较为快速的支持Directx9和Directx10的显卡来讲优化是不错的。在初期使用z测试前置得到的深度信息也是很有用的,很多功能现在都依赖于这个数据。如今,更加规范的延迟渲染像素数据也包括了更多的像素信息,比如漫反射色彩,法线,和1些特殊的材质。对渲染外星人的室内场景,延迟渲染多是最好的解决方案,但是其他的环境则不能从中受益,由于只有1个光源的情况下延迟渲染其实不能很好的发挥其优势。

致谢

此次演示文稿是很多程序员,美工和设计师们共同努力的结果。在这里我们要特别感谢Vladimir Kajalin, Andrey Khonich,Tiago Sousa, Carsten Wenzel 和Nick Kasyan. 我们已成了NVIDA的合作火伴,我们取得了他们的现场帮助而包括而不但限于G80 Directx9和Directx10方面的问题。因此特别感谢NVIDA的工程师Miguel Sainz, Yury Uralsky 和 Philip Gerasimov。同时为业界的领袖企业Microsoft,AMD,Intel,NVIDA和其余的支持过我们工作的公司致以感谢。同时为帮助我完成这篇论文的Natalya Tatarchuk 和Tim Parlett致以感谢。

援用

[ATI04] ATI 2004, Radeon X800 3DcTM Whitepaper http://ati.de/products/radeonx800/3DcWhitePaper.pdf  

[DL06] DONNELLY W. AND LAURITZEN A. 2006. Variance shadow maps. In Proceedings of the 2006 ACM SIGGRAPH Symposium on Interactive 3D graphics and games, pp. 161⑴65. Redwood City, CA  

[ISIDORO06] ISIDORO J. 2006. Shadow Mapping: GPU-based Tips and Techniques. GDC presentation. http://ati.amd.com/developer/gdc/2006/Isidoro-ShadowMapping.pdf   

[JENSEN01]  JENSEN, H. W. 2001. Realistic image synthesis using photon mapping, A. K. Peters, Ltd., Natick, MA.   

[JENSEN01a] JENSEN, L. 2001, Deep-Water Animation and Rendering, Gamasutra article http://www.gamasutra.com/gdce/2001/jensen/jensen_pfv.htm  

[LANDIS02] LANDIS, H., 2002. RenderMan in Production, ACM SIGGRAPH 2002 Course 16.  

[MICROSOFT07] MICROSOFT DIRECTX SDK. April 2007.   http://www.microsoft.com/downloads/details.aspx?FamilyID=86cf7fa2-e953⑷75cabde-f016e4f7b61a&DisplayLang=en   

[MT04] MARTIN, T. AND TAN, T.-S. 2004. Anti-aliasing and continuity with trapezoidal shadow maps. In proceedings of Eurographics Symposium on Rendering 2004, pp. 153–160, 2004.  

[MCTAGGART04] MCTAGGART, G. 2004. Half-Life 2 Shading, GDC Direct3D Tutorial  http://www2.ati.com/developer/gdc/D3DTutorial10_Half-Life2_Shading.pdf   

[MITTRING04] MITTRING, M. 2004. Method and Computer Program Product for Lighting a Computer Graphics Image and a Computer. US Patent 2004/0155879 A1, August 12, 2004.   

[SD02] STAMMINGER, M. AND DRETTAKIS, G. 2002. Perspective shadow maps. In SIGGRAPH 2002 Conference Proceedings, volume 21, 3, pages 557–562, July 2002  

[TESSENDORF04] TESSENDORF, J. 2004. Simulating Ocean Surfaces. Part of ACM SIGGRAPH 2004 Course 32, The Elements of Nature: Interactive and Realistic Techniques, Los Angeles, CA   

[URALSKY05] URALSKY, Y. 2005. Efficient Soft-Edged Shadows Using Pixel Shader Branching. In GPU Gems 2, M. Pharr, Ed., Addison-Wesley, pp. 269 – 282.  

[WENZEL05] WENZEL C. 2005. Far Cry and DirectX. GDC presentation, San Francisco, CA  http://ati.amd.com/developer/gdc/D3DTutorial08_FarCryAndDX9.pdf  

Advanced Real-Time Rendering in 3D Graphics and Games Course – SIGGRAPH 2007

121

[WENZEL06] WENZEL, C. 2006. Real-time Atmospheric Effects in Games. Course 26: Advanced Real-Time Rendering in 3D Graphics and Games. Siggraph, Boston, MA. August 2006  http://ati.amd.com/developer/techreports/2006/SIGGRAPH2006/Course_26_SIGGR APH_2006.pdf  

[WENZEL07] WENZEL C. 2007. Real-time Atmospheric Effects in Games Revisited. Conference Session. GDC 2007. March 5⑼, 2007, San Francisco, CA. http://ati.amd.com/developer/gdc/2007/D3DTutorial_Crytek.pdf  

[ZIK98] ZHUKOV, S., IONES, A., AND KRONIN, G. 1998. An ambient light illumination model. In Rendering Techniques ’98 (Proceedings of the Eurographics Workshop on Rendering), pp. 45–55.

 

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生