Unity3D实时体积光(二)

Unity3D实时体积光(二)

在上一节中,我们使用Ray march算法,在降采样的RenderTexture中实现了一套体积光,然而,我们发现,体积光在采样率较低,采样目标点远的时候,采样点之间间隔太大,就会出现难看的斑驳。Unreal Engine 4在体积光的实现上解决方案是通过原生分辨率和较高的采样率,并在屏幕空间下完成基于深度的模糊,进而增加体积光的平滑度,这样的方法虽然效果好,却大大增加了对显存和GPU流处理器的压力,因此我们这里需要一个更Trick,更高效的方法,实现一个低消耗且效果较好的体积光。

首先,我们的测试场景如下,几个方块并在一起,体积光从缝隙间泻下,这对于采样精度有较高的要求,策划常要求我们在室内的百叶窗上创造出这样的效果,以增加室内渲染的意境:

我们的测试场景

我们的第一个实现目标,在4次采样时让体积光拥有一个大致的轮廓,要知道4次采样+降采样的RT,对于体渲染来说条件是十分苛刻的,首先在没有随机采样的情况下,效果如下:

完全错位的体渲染

可以看到,体渲染完全错位,完全没有办法表现体积光的效果,我们需要对其进行优化。首先第一个优化就是使不同像素使用完全不同的采样,使整个画面闪烁起来,然后通过我们之前讲过的基于深度的正态模糊和降采样,进一步降低性能消耗,这一套流程的实现结果如下:

首先我们可以看到,图中的光影交织部分有大量的噪点,这得益于我们的随机算法,代码如下:

这段代码截取自Raymarch函数,看起来复杂,实际原理非常简单,首先,前几句我们确定了final, step, seed这几个变量,final顾名思义,是raymarch采样的终点,而rayStart和rayDir毫无疑问就是采样的起点和方向了,我们通过线性插值在采样的起点和终点间采样,因此Step则记录每一步插值权重的步长,而step.y则看起来有些不易理解,其实他的作用是确定随机采样的范围,我们将其手动设置为0.4,意思是上一个采样点在-0.5的位置,下一个采样点在1.5的位置,而当前采样点的理想采样点应该是0.5处,这时我们的随机范围则应该停留在0.1到0.9之间,这样设计的目的是每一个采样点都有较大的随机范围,同时总采样距离相对一致且采样点之间不会重复采样或交叉采样,影响渲染正确性,而这个随机算法也很有意思,图中调用的random函数定义如下:

#define random(seed) sin(seed * 641.5467987313875 + 1.943856175)

我们看到,这其实是一个非常简单的利用sin函数进行一个魔数偏移的伪随机,由于sin函数的分布相对均匀且我们这里每次偏移数值较大,可以保证一定范围内采样的随机性和均匀性,而这一句

float seed = random((_ScreenParams.y * screenPos.y + screenPos.x) * _ScreenParams.x + _RandomNumber);

才是我们这里随机计算的点睛之笔,_RandomNumber是一个依靠脚本传输的随机数,每帧都是不一样的,而上边的这一句其实是将整张图想象成一个二维数组,而UV则是数组的索引值,因此通过对这个“数组”的降维处理,获得每个像素点独一无二的随机种子,接下来的代码就非常好理解了,将每个随机数生成的种子重复利用,并生成一个区间在[-1,1]的随机数,使其配合上述的raymarch流程工作。

当屏幕充满噪点,我们需要的是将其进行双边采样和双边滤波降低整个屏幕噪点的尖锐程度。(双边滤波实际并不能降低噪点的闪烁,只能让噪点看起来变的不那么扎眼)。双边模糊的核心代码如下:

双边模糊的代码虽然长,可是却非常容易理解,本质就是一个正态的分布,只是通过提前升采样和双线性过滤获得一张与屏幕分辨率相同的RenderTexture,并通过像素深度改变采样权重,这样使得体积光在缝隙密集的地方表现的更佳了。

最后,按照国际惯例,下雨天随机采样总是与Temporal Filter更搭,我们使用Unity官方提供的Post Processing Stack V2的TAA,提高画面的整体顺滑度。

事实上我们的代码非常高效,即使在64次采样下,性能消耗也几乎可以忽略不计,在笔者的老旧笔记本上,只用了0.5ms,未来移植移动端已然不是梦。

16次采样下,加上Temporal Filter,可以看到噪点已经大大减少:

64次采样下,效果非常完美:

本篇实现已开源,下载地址:

MaxwellGengYF/Unity-Volumetric-Lightgithub.com图标

希望有兴趣,有能力,有热情的朋友来鄙人的QQ群交流图形学,群号:146025605

P.S. 加群问题:“Unity BRDF使用的高光公式是什么?”随便答出任何一点即可,望周知,谢谢。

发布于 2018-07-15

文章被以下专栏收录