屏幕空间反射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

参考

[OpenGL] 屏幕空间反射效果_opengl ssr-CSDN博客
文章浏览阅读9.3k次,点赞7次,收藏22次。概念引入 屏幕空间反射又称SSR,是SS系列算法之一。该算法基于延迟渲染,也就是说,在动手实现SSR前,需要具备延迟渲染相关的知识,主要包括:G-Buffer相关信息的写入,根据G-Buffer还原出位置、视线向量、法线等一系列信息等。 算法本身的原理非常简单,也就是对于屏幕空间上的物体的每个像素,根据该像素对应的法线和视线信息,求解出反射向..._opengl ssr
Unity URP实现屏幕空间反射(SSR)
Unity版本:2022 URP版本:14.0 基础SSR很简单,更重要的是如何对其进行优化和应用。在本文中,首先完成了在视空间的SSR,然后优化到屏幕光栅空间SSR,最后加上二分和Dither。 最后更新了一下HiZ,这是优化最大的…