屏幕空间反射 VR (URP)
前言
之前的那个VR中采用复用阴影贴图的方式,用独立的相机渲染反射贴图还是有很多不足,因为是复用的阴影贴图,如果镜子中的物体没有在正常相机内有阴影的话,镜子中也不会有阴影。
所以还是想尝试一下SSR即平面空间反射在VR单通道模式下的实现。
分析
目前URP还没有原生支持SSR,也不想再重复造一次轮子了,这里先选用ShinySSRR作为基础的SSR,在它的基础上适配VR。
直接在单通道下使用测试一下,理所当然的当然失败了。
先简单看一下它原生的方式,大体分为几个步骤。
- 首先是通过要反射的物体的顶点和法线去计算每个像素的反射方向,然后通过深度图不停的去步进采样,得到最终要采样的像素的UV。同时这里记录了每个像素的粗糙度。
- 通过上面得到的UV,去采样一次屏幕颜色
- 经典的Kawase模糊去模糊反射贴图
- 最后依据设定的模糊程度和粗糙度再去采样对应的模糊程度的贴图,与现有的颜色相混合。
填坑
这里的问题就出在第一步的步进上面,它是在屏幕空间去步进的(不知道该怎么表述这一点,它的步进、碰撞判定,全是在屏幕空间)。至于为什么能直接在屏幕空间去步进,还没有完全理解。但因为单通道的特殊性,单通道的相机的PV矩阵在这种情况下是不正确的。于是还是改为了在视角空间下去步进。
对比发现,相同的迭代步数,确实不如直接在屏幕空间步进的效果好。
当然这里它做了很多优化,比如从近平面去截取,依据起点和终点的像素距离去降低迭代次数等等。
Occlusion
因为VR中的实际显示面积并不是一个矩形,而是一个类似圆
这恰好弥补了ssr边缘位置的缺陷,所以ssr在VR中实际的观感还是不错的。
但因为这毕竟不是原生支持的ssr,在与urp自带的lit着色器搭配使用时,并不能和urp自身的反射融合的很好(HDRP非VR模式下的SSR就可以根据当前像素是否能从SSR中获取反射而决定要不要使用反射探针)。还需要一些刻意的调整以防止和反射探针混淆。
法线来源
这里除了使用插件原生的从模型顶点和法线贴图生成法线,也可以直接使用URP自带的NormalTexture,打开SSAO即可。所以SSR和延迟管线才是绝配,但又因为延迟管线无法使用SMAA,所以这里只能舍弃延迟管线了。
使用NormalTexture还有一大好处是可以支持任何在shaderGraph中生成的shader。比如这里的用flipbook和视差贴图做的石子地面就可以和SSR无缝衔接起来。