[图形学] Killzone:Shadow Fall中的屏幕空间反射效果

reference:Siggraph 2014 http://advances.realtimerendering.com/s2014/

        今天的演讲主要是我们做的两个效果,这些效果极大地影响了我们设计游戏关卡的方式。对错过早上会议的人我们先进行简短的关于时域重投影的介绍后,我们将开始描述我们的实时反射系统和我们的体积照明技术。

 

         Guerrilla games是索尼全球工作室组的一部分。我们约有200人在阿姆斯特丹市中心工作,我们在剑桥还有一个较小的姐妹工作室。您可能知道我们是各种Playstation平台的killzone游戏制作商,最近,我们发布了Killzone Shadow Fall,PS4独家发布游戏。

        我们认为,新平台让Killzone走向新方向,并探索一些新技术的好机会。如果您已经知道以前的Killzone游戏,你会注意到我们已经提出了不少技术上的突破点。我们的技术目标是实现平台定义的视觉效果,我们选择了将大部分的精力投入到照明技术中。

       我们在早期就已经切换到基于物理照明和泛光灯,我们还确保从一开始就有反射和体积效果,以便美术可以设计出具有这些效果的关卡,而不是在已经完成的游戏上添加这些特征。

        如果您想了解更多信息,请在周三下午2点访问我们的制作演讲。

        现在,让我们以两个幻灯片了解一下时域上的重投影。 

        考虑到目前渲染帧的方式,我们会发现这种做法实际上非常愚蠢——我们将所有GPU周期用于复杂的光照模型,体积和粒子等效果,但是我们只在屏幕上显示了一次,就丢弃了它们重新开始渲染。 

       重投影的基本思想与大多数连续帧类似,我们可以重用来自前一帧的信息,例如,用于提高当前帧的质量,或者节约一些GPU时间,因为我们不必再次进行重复的相同计算。

        你可以做些什么...

        渲染像素时,可以使用运动矢量来查找前一帧中相同像素在屏幕中的位置。

        然后,你需要确定它是否是相同的像素。例如,可以检查z缓冲区中的预期深度,你知道,它可能被某些东西遮挡了。或者可以检查颜色是否与像素的相邻颜色近似。

        这个技巧在许多算法中很有用,例如抗锯齿,上采样,景深,泛光以及AO。

        准备好了吗? 

         我们的目标是构建一个通用系统,可以在任何表面上工作而无需特殊情况处理。我们认为我们是第一款在默认情况下启用反射并深入集成到游戏外观中的游戏。

        我们的反射由三部分组成:我们有一个实时光线追踪系统,它提供可见场景的动态反射;我们有一组静态的本地化立方体贴图,这为某些游戏区域提供预渲染的反射;最后一部分是预渲染的背景立方体贴图,它提供了无限远的环境反射。

        系统的每个组件都能够回退到下一个组件。如果实时反射不能提供结果,我们检查本地化立方体贴图。如果没有本地化的立方体贴图,我们使用背景的立方体贴图。

(视频演示:本地化立方体贴图放置的快速演示)

 

        反射光泽度取决于两个因素。表面粗糙度决定了反射锥孔径:粗糙的表面会导致反射矢量的扩散,我们需要一个宽的锥体;光滑表面上反射矢量在相同方向上更多,并且锥体更窄。

        第二个重要因素是反射光线传播的长度,反射锥随着长度变宽,更远的反射变得更加模糊。

        对于立方体贴图反射,我们根据反射锥半径来确定光泽度,随着反射光线击中立方体贴图边界(无zbuffer)。

        为了确保反射在视觉上和实时光照或光线追踪相同,我们预过滤立方体贴图mipmap以匹配我们的镜面BRDF分布。

        我们的实时反射有三个主要阶段,我们将在以下幻灯片中讨论细节。

        我们利用屏幕空间光线追踪为每个像素找到单一的反射颜色,然后我们执行滤波和重投影,以在屏幕上获得光泽反射和稳定的图像。我们在最后合并实时反射和立方体贴图反射。

(视频演示:)

 

 

         光线追踪pass的重要细节比较少。我们不使用任何类型的深度缓冲层次结构来加速光线追踪,而是对命中像素使用普通的线性搜索。部分原因是我们没有时间完全优化层次结构生成和搜索了。优点是,我们的光线追踪pass非常连贯,具有可预测的质量。

        光线追踪的步骤在屏幕空间中是固定的。我们在开始时计算一次反射向量方向,并确保我们在主方向的每个步骤中粗略的覆盖了两个像素。表面的粗糙度会增加步长,而光滑的表面步长较短,因为反射需要保持精确。具有模糊反射的粗糙表面可以使用更长的步长。

        我们将z-buffer视为平滑高度场,并对最后命中的采样深度做插值作为结果。即使对于较大的步长,这也可以很好地工作。重要的诀窍在于我们不使用当前帧来获得反射颜色,而是使用重投影并从前一帧中选择颜色。这里没有相似性检查,我们只接受缓冲区中的内容。

        通过这种方式,我们可以在反射中进行后处理和粒子效果。我们得到累积的二次反射反弹,这非常地酷,因为这种方式的反射实际上可以作为各式各样的廉价GI(全局照明)。

        当然,我们会减弱屏幕边缘的反射,以避免走样。

        有噪声的原始反射缓冲区,您可能会注意到那里的粒子和体积: 

       光泽度-较小的值是更为光滑的表面: 

        掩码-白色表示命中,黑色表示反射未命中。灰度值用于淡出靠近屏幕边缘的反射。

        此处是包含启发式的,允许射线通过武器附近的物体,否则将得到一个没有反射的大片区域。

        远离相机的光线会忽略比原点更近的物体。

        在下一步中,我们从光线追踪缓冲区生成mip-map链。我们再次使得过滤器匹配我们的BRDF,使用长度为7的可分离模糊算子。我们会使用前一次传递的掩码来丢弃反射未命中的像素,在这种情况下,我们使用中心样本。

        滤波没有考虑深度,并在非常粗糙的反射上可能会在表面上“泄露”,但我们并没有在游戏中发现什么问题。 

        以下是光泽度滤波链的示例: 

 

        然后,我们继续构建实时的反射缓冲区,并使用光泽度值来选择正确的mipmap。

        光泽mipmap中没有很好地捕获锐利的反射,因此我们为非常低光泽度的区域添加了直接的模糊。

        我们指定一些条件来确保它只在需要的地方执行,这使得它比预先模糊整个顶部的mipmap更优了。

 

        反射以半分辨率渲染。

        我们不执行滤波,我们将在下采样期间每帧选择2X2四边形的不同像素。

        在四帧之后,我们已经有效地覆盖了全分辨率图像,并且已经知道了每个像素的反射,但是我们的图像抖动严重,无法使用。

        正如标题所提,我们希望使用重投影来获得一些更好、更稳定的东西。

        帧最终的反射图像来自前一帧和当前帧缓冲区的图像混合。它仍然是半分辨率的,但累积的交错相似可以作为超级采样。

        我们使用重投影来校正像素的抖动,我们使用Hugh Malans颜色邻域来测试像素的相似性。

        一个比较好的技巧是使用已经计算过的邻域的平均值在完全反射未命中的区域中稍微扩大图像,其中掩码为0。 

        右侧-通过重新投影来软化图像,扩张填补图像空白的位置。

        我们的GPU分析器的一些性能数据:

        我们实际上使用1/4分辨率深度进行光线追踪(记住我们有两个像素步骤),但初始的反射向量计算仍然来自全分辨率数据。 

猜你喜欢

转载自blog.csdn.net/ZJU_fish1996/article/details/88913781
今日推荐