[程式] 场景雪地的做法:延迟雪地变形 (上)

楼主: jugu (硬盘一定是故意的)   2016-07-19 23:25:12
粉丝团文章连结:
https://www.facebook.com/life.is.kuso.game/posts/278181642573356
这个做法是看完GPU Pro7这本书的心得,在此要先感谢作者Anton Kai
Michels跟Peter Sikachev。
这次要介绍的是古墓奇兵:崛起(Rise of the Tomb Raider)中的雪地
做法,有玩这游戏的人可能会注意到,雪景做得还不错。这系列的文章
将分成上、中、下三篇,上篇会先讲解如何做出脚踏下的深度,中篇则
会介绍周围隆起的雪堆计算方式,来让场景显得更真实,下篇则会说明
雪地的脚印痕迹如何随时间恢复。
用于古墓奇兵的雪地做法,是一种被称为延迟变形(deferred deformation)
的新技术,地形变形在实时渲染中,一直是个已知的未解决问题,以往
的解法呈现的细节不够让人觉得真实。而延迟变形则提供了一个有扩充
性、低内存、又可精细到公分等级的解决方案,并且在任何地形都能
呈现任意数量的变形,其细节不只能呈现走过的凹陷,甚至能呈现边缘
被影响所造成的隆起,以及根据条件决定是否慢慢回填凹陷。
提到雪景, 蝙蝠侠:阿卡汉始源(Batman: Arkham Origins)的效果其
实很不错(注一),不过其雪景只发生在平面的地形,在此就不详谈,由
于GPU在DirectX 11中的硬件支援,这种技术基本上利用渲染流程中去
处理,因此能做出非常准确的变形,可是却无法用在任意地形上,且只
会有凹陷而不会有边缘的隆起。
(https://cdn-images-1.medium.com/max/1200/1*w539g2-wHVmSLvc-hd4K2Q.png)
在解说技术之前,需要先说明会用到的一些名词,列举如下:
雪地高度(snow height):
 要变形的雪地的垂直座标(通常为vertex.z)
变形点(deformation points):
 会造成变形的物件的3D座标位置
脚高度(foot height):
 变形点的垂直座标(通常为point.z)
拖曳凹陷(trail depression):
 拖曳痕迹的一部分,为雪地高度下踩下的部分
拖曳隆起(trail elevation):
 沿着拖曳痕迹产生的小凸起,当推开雪时应该自然产生的效果
变形高度映射(deformation heightmap):
 一张用来储存变形的贴图,32bit,1024*1024
凹陷深度(depression depth):
 (雪地高地-脚高度)的绝对值
变形着色器(deformation shader):
 将变形输出到变形高度映射的着色器
填充着色器(fill shader):
 用来计算在暴风雪中回填拖曳痕迹的着色器
雪地着色器(snow shader):
 用于变形的雪的材质的着色器
想像一下原本的地形网格上,有一层雪的网格(mesh),然后有不定数
量的动态物件造成雪地变形,而要渲染雪的变形时,我们必须先得知
动态物件、雪跟地形之间的高度关系,所以必须先利用从正上方俯视
的方式,将这两层网格分别渲染到两个高度映射来得知高度,然后再
将动态物件渲染到一个变形高度映射,取得其在雪跟地形之间的逼近
值(clamp),当渲染雪的变形的时后,再从做好的变形高度映射取样,
来取代雪原本的顶点与法线(normal)。
(作法的思路)
(https://cdn-images-1.medium.com/max/1200/1*tal2N7TYFrmzW-X6r7XonQ.png)
而这个简单的做法有两个缺点,一是必须先从鸟勘视角渲染一次来做
出两张高度映射,二是每个动态物件需要一个绘图指令(draw call),
解决的方式就是接下来要介绍的延迟变形。
延迟变形的思路,第一个就是不用先做一次雪网格的高度映射,而是
在雪的渲染流程中,去取用雪网格的顶点位置即是其高度,第二个是
变形的逼近值在被取样时才计算,而非渲染时。所以精确的变形计算
是在渲染雪的时后,才称之为延迟变形。重点是要将雪的高度从雪的
顶点着色器(vertex shader),传到雪的像素着色器(pixel shader),
以计算每个像素的法线。其算法如下:
(延迟变形算法概要)
(https://cdn-images-1.medium.com/max/1200/1*M_xzTuHTQsm_BikvLawAqw.png)
延迟变形算法中的一个重点就是:把变形当成一个二次曲线(quadratic
curve)。借由近似动态物件形状的点,去计算其变形高度。算法如下:
 变形高度 = 点高度+ (到点的距离)平方 × 美术缩放值
这些变形点会被放到一个全域缓冲(buffer),而每个变形着色器则会
被分配到变形点周围32像素平方的区域(1.64 m平方),然后利用原子
级同步最小值(atomic minimum)计算,输出受影响的像素的变形高度
。由于可能有不同的动态物件去影响到同一个高度映射中的像素,所
以原子级同步取最小值是必须的。因为在DirectX 11中能够做这种运
算的只有unordered access view(UAV),其形态是32-bit integer,
因此变形高度映射的型态也必须是R32_UINT。
注一:如果对蝙蝠侠的做法有兴趣,可以参考GDC的资料
(http://www.gdcvault.com/play/1020177/Deformable-Snow-Rendering-in-Batman)
作者: riveranb (River)   2016-07-20 08:23:00
推,好文
作者: wangm4a1 (水兵)   2016-07-25 03:01:00

Links booklink

Contact Us: admin [ a t ] ucptt.com