屏幕空间反射SSR Vulkan实现
简介
实时渲染中重要的一环是计算间接光照,间接光照有多种实现方式,屏幕空间反射是其中的一种,我将尝试实现屏幕空间反射,把它加进我的渲染器中。
屏幕空间反射(Screen Space Reflections,简称SSR)是一种用于实时图形渲染的技术,主要用于模拟镜面反射的效果。它基于屏幕空间的图像数据,通过在像素级别计算来模拟反射效果,通常用于视频游戏和计算机图形中。
SSR 的基本原理是在屏幕空间内,对每个像素的位置进行采样,然后检查这个位置是否能看到具有反射性质的表面(如水面、镜面等),如果可以,就计算出对应的反射位置,然后将其反映在最终的渲染结果中。
尽管如此,SSR 仍然是一种广泛应用于实时图形渲染中的技术,它能够有效地增强图像的真实感和视觉质量,特别是在模拟涉及到反射的场景时。
--ChatGPT
原理
原理就是在视口空间中做简单的raymarch。
对于屏幕上任意一点\( p \):
1.根据摄像机方向\( L \)与当前点\( p \)的法向\( N \),计算反射方向 \( RDir = reflect(L,N) \)
2.从p点出发,沿着反射的方向进行光线步进:\( rayPos = p + step * RDir \),其中step为步进的长度
3.对于每次步进,比较\( rayPos \)和\( rayPos.xy \)对应屏幕空间的\( z \)值。
->如果相差小于一个阈值 \( eps \) 则发生相交,取该点的颜色为\( p \)点的反射值;
-> 否则回到第2步循环。
原理十分简单,直接出的效果也不太理想,需要根据光线步进的距离、采样点的粗糙度等因素进行衰减;同时由于是步进迭代的算法,时间开销十分大,需要考虑加速步进,如二分搜索、Hi-Z等优化方法。
实现
1.一开始实现的最原始的SSR效果如下图。步长为0.2。
2.可以考虑调整步长,将步长调整为0.02时效果如下图,效果好一些,但是性能开销很大
3.添加根据步进距离衰减,效果可以更好一些,如下图,我使用的衰减公式为 \( weight = e^{-distance * attenuation } \),其中\( distance \)为光线步进的长度,\( attenuation \)为衰减系数。
4.尝试使用二分搜索寻找相交点,但是效果好像不明显
5.尝试根据金属度和粗糙度确定衰减,直接按照系数 \( metal * rough \)再进行一次衰减,这里换了一个场景,地面是非金属,粗糙度0.5,模型大部分是金属,从图中可以看到一定的色染效果。
渲染结果 | SSR texture |