【GDC2013】Particle Shadows & Cache-Efficient Post-Processing

本文是对NVidia在GDC2013上关于粒子阴影以及AO加速算法的学习记录,如有谬误之处,请不吝批评指正,这里是原文传送

1. Particle Shadow

Assumption

传统粒子(特效)阴影的实现是建立在穿透每个粒子的光强以(是粒子的透明度)衰减的假设上的,按照这种假设,经过多次穿透之后得到的光强比例就是多个粒子衰减力度之积。

Translucency Map

Crytek 2011就是用这种方法为场景添加了一张叫做Translucency Map的半透阴影贴图,这张阴影贴图只采集各个透明物体绘制的光照视角的深度数据,各个半透面片按照特定的顺序绘制,通过累乘完成blend即可输出结果。

Limitations

这个方案的不足之处在于渲染的半透粒子没有自阴影。

Volumetric Self-Shadowing

关于自阴影的实现方案,前人给出过很多方法,其中Fourier Opacity Mapping方案还成功被应用在《Batman:Arkham Asylum》上。

不过这些方案都有着一些不足之处,比如无法满足如下的几点要求:

Goals

想要成功应用在各种产品上,给出的方案必须要具备伸缩性,即在任何场景下都能够具备较好的性价比。

本文介绍的Particle Shadow Mapping能够很好的填补此前的空白。

Particle Shadow Mapping

所谓的Particle Shadow Map,实际上是一张光源视角的3D贴图,每个voxel存储对应位置的shadow(Transmittance)信息。

算法步骤

整个算法可以通过如上四步完成,下面对每一个执行步骤进行解说。

第一步,将这张3D贴图清空,每个voxel重置为默认值(0.0)。

第二步,将前面Translucent Map实现中的Transmittance写入到各个对应的voxel中,这个过程通过VS/GS/PS/OM配合完成:
1. VS,渲染整个粒子Geometry
2. GS,为每个voxel生成一个对应的particle(如果处于粒子范围内)
3. PS,向voxel写入当前particle的透明度数据
4. OM,Output Merger用于实现多个Particle叠加时Blending,输出累乘后的Transmittance结果

第三步,沿着光线前进的方向,不断的对后面的voxel的Transmittance进行填充

第四步,将PSM采样得到的transmittance用在场景中粒子的渲染中。

下面对这个算法的一个实现细节进行介绍。

voxel格式
每个voxel用一个FP32来存储的话,会太浪费了,这里尝试用8_UNORM来表示每个voxel的数据格式,那么256x256x256就变成了256x256x64的4x8_UNORM,四个通道对应连续的四个voxel

为什么不直接使用256x256x256,每个像素是8_UNORM呢?猜测可能是硬件不支持?

插值滤波
因为前面将4个voxel packing成一个32位的数据,因此无法直接使用硬件的三线性插值,这里改成两个双线性插值

Coverage优化
3D贴图覆盖的范围大部分都是空白的,只有少部分是被粒子所覆盖的,对于空白的区域,理论上可以跳过复杂的计算,直接使用前面的voxel数据进行填充即可。

这里给出了几种尝试思路:

  1. 额外slice策略
    单独抽取一个slice用于表明粒子的覆盖范围,对于不在覆盖范围内的voxel就跳过处理。但从实际表现来看,性能并未得到优化,这是因为将粒子光栅化到这个额外slice,会导致fillrate上涨,从而导致执行时间增加
额外slice策略
  1. double viewports策略
    将粒子光栅化到两个D3D11的Viewport中,其中
    viewport1的分辨率为8x8,用于给出粒子的大致覆盖范围(保守)
    viewport2的分辨率256x256,这个跟之前一样,是用于对PSM的结果进行处理的viewport

viewport1的分辨率下降是性能提升的关键,在最终的表现上,执行时间减少16%

double viewport策略

粒子API渲染优化
使用DX11提供的Tessellation功能,使用DS对PSM进行采样可以得到比PS执行更高的效率

粒子API渲染优化

2. Cache-Efficient Post-Processing

现有算法SSAO以及SSDO等都需要通过大尺寸的filter加上jitter实现质量的提升。相邻像素在进行数据采样的时候,由于采样pattern不同,导致数据的空间局部性效用下降,cache miss率上升,执行效率低。

此外,由于相邻像素的随机pattern都不相同,因此相邻像素之间的采样结果无法重用,所以也很难通过CS来进行算法加速。

为了提升执行效率,业界给出了很多优化算法:

优化算法现状

收缩采样sample的分布范围
其基本思路是将相邻像素的采样sample限定在一个较小的sector中间
,每个sector取值为1/4 kernel size。

这个算法的优点是可以在确保随机的基础上得到尽可能高的数据空间局部性效用,但是并不能完美的解决问题,因为在一些kernel尺寸较大的地方,这个做法的收益非常有限。

多级分辨率输入贴图
根据收缩采样sample的分布范围的算法存在固有缺陷,如果kernel尺寸增加,收缩sample分布范围的做法就失效了,可以通过使用多级输入贴图来规避这种情况。而多级分辨率输入贴图算法的基本思路为:

  1. 距离当前待渲染像素较近的采样点,使用高分辨率输入贴图。相邻像素之间对应的采样点差距较小,不违背数据局部性原则
  2. 距离当前带渲染像素较远的采样点,使用低分辨率输入贴图。距离较远的采样点在低分辨率贴图上的位置相距也不会太远,保留了局部性原则

这个算法的多级输入贴图可以通过mipmap实现。其问题在于即使使用mipmap来增强数据局部性效用,相邻像素采样点的抖动依然无法最大程度的使用局部性效用。

本文给出的算法叫做Interleaved Sampling Patterns。

Interleaved Sampling Patterns
算法的基本思路是通过将各个采样点从全分辨率拆解出来,分别进行随机化排列,最后按照regular采样来得到随机pattern,主要有如下几个实现步骤:

  1. 按照采样点数目对全分辨率输入贴图进行拆解
Deinterleave Input

图示使用的是4张子图,对应的是4个sample,如果sample数目扩展到16(4x4),那么就需要16张子图

  1. 对各个拆解后的子图分别进行随机化排列


    Jitter-Free Sampling

在这一步中,会为每个子图设计一个固定的随机pattern,子图内部每个像素都是按照这个随机化模式来计算子图对应的AO(实际上这个加速算法不止可以应用在AO上,还可以应用到其他具有类似困扰的随机采样计算算法中,这里为了方便叙述,直接使用AO来进行说明);而不同的子图,随机化模式存在区别。

这一步会分为多个pass来完成,每个pass对应一个子图的输入,也对应一个子图的输出(AO结果)。

Jitter-Free Sampling算法优点

这个算法能提升性能主要是由这第二步决定的。因为通过前面的拆分,我们计算时所使用的就是低分辨率的输入贴图,这就有助于提升渲染性能;此外,由于每个pass对应的子图中各个位置的随机pattern是固定的,因此也就解决了前面由于相邻点随机pattern不同对数据局部性效用的破坏,提升cache的命中率。

  1. 结果重组


    Reinterleave Results

经过第二步之后,我们就得到了多个不同子图的输出结果,为了将这些结果的信息都用上,这里需要将结果按照第一步的处理逻辑进行反向重组回去,从而得到全分辨率的AO结果贴图。如果子图输出的结果都存储在TextureArray中,那么这个地方,可以通过一个DrawCall(Viewport分辨率为全屏分辨率)完成重组

  1. 质量提升
    通过直接重组得到的结果会比较差,后面会说,这是因为各个子图的采样点是有限制导致,为了提升显示质量,这里还会通过一个(通常是横向+纵向高斯模糊)模糊处理来提升显示质量,具体细节就不展开了。

性能表现
经过测试,全分辨率SSAO消耗大概是4x4 Interleaved SSAO的2~3倍。此外,这个算法在贴图命中率上面也有优化:
通过工具(NVidia:PerfKit,AMD:GPUPerfStudio 2)可以查询贴图cache的命中率,经测试:Non-Interleaved的贴图命中率为38%,而Interleaved算法的贴图命中率为67%。

光说性能不说质量就是在耍流氓,经过效果对比,我们发现在质量上,HBAO+比SSAO更优秀。

那么这个算法是否就没有一点缺点呢,这也不是,实际上,这个算法的采样uv存在限制,我们在第二步计算各个子图的AO时,采用的采样点数据也是子图中的,因此按照全图分辨率进行计算且采用4x4 interleaved模式的话,各个采样点与当前被计算像素之间的距离则是以4个像素为单位的,相当于123等间隔处的采样点无法使用,从而使得效果上回存在一些瑕疵。

Drawback

这个算法目前已经被应用在下述等多款大作中,说明业界对其的认可度还是非常之高的:

  • The Secret World (2012)
  • ArcheAge Online (2013)
  • Far Cry 4
  • Assassins Creed Unity
  • The Crew
  • Call of Duty: Ghosts
  • Assassin's Creed IV: Black Flag
  • The Division
  • Rise of the Tomb Raider
  • Fallout 4
  • Assassin’s Creed Syndicate
  • Rainbow Six Siege
  • The Witcher 3: Wild Hunt
  • World of WarCraft: Warlord of Draenor

你可能感兴趣的:(【GDC2013】Particle Shadows & Cache-Efficient Post-Processing)