如何在Unity中实现Stochastic Screen Space Reflection效果

如何在Unity中实现Stochastic Screen Space Reflection效果

这是侑虎科技第411篇文章,感谢作者CG-Bull供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。
UWA QQ群2:793972859(原群已满员)

关于作者:https://zhuanlan.zhihu.com/p/38303394
作者也是U Sparkle活动参与者,UWA欢迎更多开发朋友加入U Sparkle开发者计划,这个舞台有你更精彩!


这篇文章里,作者详尽介绍了如何做一个符合自己需求的SSR。因为Unity自带的PostProcess里面的SSR效果不太理想。作者陆续找到的一些方案也不尽如人意,比如一款CandelaSSRR纯镜面效果确实很好,但是粗糙表面居然直接就是正太模糊;论坛上一个免费的Stochastic SSR,结果原作者用ImageRender来做,导致和透明物体的排序会出现问题(如图)。

请输入图片描述

另外,这个Stochastic SSR的RayMarching求交也比较直接。导致反射会很拉长(如图)。

请输入图片描述

因此本文作者决定参考这些大神的方案,自己动手做一个满意的SSR。首先把一些方案里面的主要计算内容提取了出来,分别是RayCasting,Resolve,Temporal,Combien四个部分。最后选择使用CommandBuffer来处理这些内容。因为这样自带Forward物体遮挡。
Screen Space Reflection 学习笔记:
https://blog.csdn.net/hehemingsgc6/article/details/53888902
在Unity中实现屏幕空间反射Screen Space Reflection(1):
https://www.cnblogs.com/yangrouchuan/p/7574405.html

对于SSR原理如果不清楚,可以去看如上两篇文章。接下来分享一下主要的制作流程。需要注意的点就是RayCasting_Linear的PixelShader,使用了两张RT输出。第一张分布存储HItUV和HitDepth以及SSR的Mask,第二张则存储计算出来的采样概率分布(rayPDF项),这里的rayPDF的XYZ项存的则是被粗糙度影响的法线分布效果,可以做出那种越粗糙反射越拉丝、狭长、模糊的反射。rayPDF的A存的则是重要性采样得到的方差,后面会拿来做Resolve加速采样去噪。这里主要加入了一个厚度判断求交,如果不这样做会产生本文第二张图那样的错误拉长(本来是用背面深度来做的,因为这样精度准确,后来消耗过高就换成了常量厚度(Thickness),背面深度方法依然保留着)。

请输入图片描述

请输入图片描述

然后在CS里面就需要把上面提到的两个RT取出来。因为后面的ResolvePass(去噪和采样反射效果阶段)还会用到。

请输入图片描述

请输入图片描述

请输入图片描述

接着就会进入RsolvePass,这个Pass会把HitUV拿来采样反射贴图,HitMask算反射遮罩(混合Cubemap用),同时用HitPDF和HitDepth算一个相邻像素共用一个采样样本(因为根据SSSR的PPT描述,一定程度上相近的两个像素得到的反射可能会是一个样子,感觉和NV的SVGF有异曲同工之秒)。最后把结果结合起来就是最终的反射效果了。然后我们把这个结果再用CB存到一张RT里(因为即便进行了相邻像素共用一个样本还是会产生很多噪点,后面还会加入Temporal来过滤噪点)。

请输入图片描述

请输入图片描述

请输入图片描述

至此,SSR的效果基本成型。接着就可以来Temporal过滤(目的是进一步消除噪点)。
这里的过滤方法来自Playerdade的GitHub的开源项目:
https://github.com/playdeadgames/temporalgithub.com

请输入图片描述

请输入图片描述

请输入图片描述

最后得到的TemporalAfter就是最终的反射效果了。就可以和主场景里面的MianTex进行混合来输出到屏幕显示最终效果。(这里面要传一个SceneColor给Shader去做混合。因为前面的Marching阶段Bilt的关系,内置的_MainTex基本变样了,所以手动传递一个SceneColor进去)。在CombientPass利用之前TAA过滤过的RT和传进来的SceneColor以及之前算好的SSRMask进行混合(同时加入Fersnel的计算,比较符合物理现象)。

请输入图片描述

请输入图片描述

请输入图片描述

请输入图片描述

到现在基本上PPT里面的效果大部分都实现了。再来放一些截图。

请输入图片描述

请输入图片描述

请输入图片描述

请输入图片描述

这张是使用了背面深度判断求交的,可以看到反射拉长的效果被完美消除,精度和平面反射有一拼

请输入图片描述

请输入图片描述

这张是也使用了背面深度判断求交

请输入图片描述

请输入图片描述

请输入图片描述

到此效果基本就是实现了。后面预计还会更新优化篇和生产结合篇。优化篇主要会优化光线求交效率,并且在没有背面深度的情况下得到反射比较精确的效果,同时还会做一些HiZ的内容已经使用更现代化的光线追踪方式。生产篇则会说一些使用方法,预计还会在做一个简化版的SSR给Forward材质和透明材质使用。

最后献上第一篇的源代码:
https://github.com/haolange/Unity-Screen-Space-Reflectiongithub.com

文末,再次感谢CG-Bull的分享,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(UWA QQ群2:793972859)
也欢迎大家来积极参与U Sparkle开发者计划,简称"US",代表你和我,代表UWA和开发者在一起!

  • hero 发表在 2018年07月05日 回复

    方便把源码贴一份么

    • CGBull 发表在 2018年09月03日 回复

      你不看完的么。。最后不是放了嘛。