基于RayTracing 的ScreenSpaceReflection

我要开发同款
啊克ca2023年03月03日
212阅读
所属分类Unity

作品详情




基于RayTracing的Screen Space Reflection是我独立完成的一个渲染feature。

Screen Space Reflection是一个在传统Grapic管线下难以实现的效果,因为传统管线并不能记录到屏幕外和没有显示的像素的数据,所以当你使用RayMatching技术反射到一些你看不到的像素时,就不能正常渲染。或者镜像再渲染一次,这样的渲染开销基本就翻倍了,除非是特定场景的特殊优化,不然没人这样做。但是在RayTracing下,这些都能很好的被解决。但是RayTracing本身的问题是,一个需要DX12,一个需要较大的显存以及本身消耗巨大。所以在过去,大家都是用RayTracing做烘培,但是现在已经出现了RayTracing的Runtime算法,这样使RayTracing可以在PC游戏上得到很好的应用。

问题及解决方案:
1 代码兼容的问题,Raytracing管线虽然提供了整体的渲染数据,但是渲染部分仍然需要复用当前管线的代码。其中会有很多信息是传统管线中存在,但是Raytracing管线中没有的,比如坐标系的变化矩阵。还有一些采样函数的使用不同以及一些语法不同。这部分只能靠良好的代码管理能力去解决,最后通过宏去完成了兼容。

2 RayTracing消耗非常巨大,所以需要一个非常好的算法去优化。目前主流的算法都是用重要性采样和MotionVector采样历史帧信息的方式去得到当前帧信息得方式,在将当前有噪点的图片通过高斯模糊去噪。重要性采样解决了在较少的射线下,可以得到一个噪点较少的图(目前我们一个像素只会有一条到3条的射线)。但是在几条射线下几乎是不可能完成一个近似的球面积分(蒙特卡洛积分)的运算的,高精度下烘培,我们都需要几千条射线才能完成一个像素的球面积分计算,所以这里我们需要使用历史帧的信息(这种算法来自与TAA)。我们通过记录MotionVector来找到当前像素在上一帧中信息(如果找不到则默认为当前色),这样就可以累加每帧的射线信息。在60帧的情况下,几秒后我们一个像素就会累加几百条射线。在通过重要性采样和模糊算法,我们可以得到一个相对不错的效果。唯一的缺陷是,在相机发生快速变化时,粗糙度交高的地方,也就是漫反射越明显的地方会有噪点。这个目前只能通过调高每帧的射线数量去解决,但是射线数量是将性能N倍放大的参数,所以RayTracing目前最好是20系列以上的N卡。

3 处理采样的mip问题,RayTracing中mip层级的计算是要自己完成的,这点跟传统管线差异很大。该算法来自 RayTracing Gems,根据射线距离相机的距离,计算采样的mipLevel。最终我实际测试的效果非常好,几乎跟传统管线一致,唯一的缺陷是编码上我们需要所有修改曾经的Simapler函数,试图想用编程技巧去解决这个问题,但是在所有可能性被否定之后,目前还是挨个去替换了。

(该功能已经是完整能上线的版本,但是因为版权问题我不能上传任何相关的截图,所以只能传一份测试阶段的图。)
声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论