MAKE · WRITE · SHARE

Unity-URP延迟渲染SSR

SSR(Screen-Space Reflection,屏幕空间反射)沿表面的反射方向寻找屏幕深度中的交点,再读取该位置的场景颜色。它利用了当前帧已有信息,也因此无法看到屏幕之外或深度层之后的内容。

本文以 2023 年 3 月 26 日笔记为主,合并后续 Hi-Z 实现思路。重点区分视角空间射线、屏幕步进、深度判定与最终合成,不把“模糊一下”当成完整的粗糙反射。

原 URP SSR 研究画面

1. 输入与空间约定

基础输入通常包括深度、法线、场景颜色,以及粗糙度或反射 Mask。深度重建为观察位置后,法线也要转换到同一空间。

若 V 指向相机,入射方向为 -V,则反射方向可写成 reflect(-V,N)。向量定义与法线朝向必须一致,不能把世界法线和观察位置直接混用。

场景颜色一般应取自适当阶段,避免把本次反射结果递归采回自己。透明、后处理、曝光与历史颜色也会影响结果语义。

2. 沿射线做深度判定

1
2
像素 → 重建起点 → 计算反射方向 → 逐步投影到屏幕
→ 比较射线深度与场景深度 → 交点细化 → 读取颜色

射线样本与深度图需要在同一深度定义下比较。设备深度是非线性的,直接用固定阈值相减通常不能表示固定世界厚度。

单层深度无法知道物体真实厚度,Thickness 是一种容错近似。阈值过大产生穿墙,太小又漏掉薄表面。二分细化只在已有合理交点区间时有意义,不能修复完全漏过的几何。

3. 为什么采用屏幕空间 DDA

观察空间等距步进,投到屏幕后并不等距,可能近处跳过像素、远处又重复采样。DDA 类方法沿屏幕主轴组织步进,让样本覆盖更均匀。

观察空间步进投影后间距不均的原记录示意

但线性插值屏幕坐标时,观察深度不能随便做普通线性插。需使用与透视投影一致的插值关系,正确处理起点、终点、裁剪和深度区间。

屏幕空间射线步进原理示意

4. Hi-Z 是深度层级,不是梯度

深度金字塔的粗层代表更大屏幕区域,可帮助判断整段区域是否可能相交。能安全跳过时走大步,可能命中时下降到更细层级。

原笔记“从最小 Mip 开始逐渐增大就缩小范围”的说法混淆了索引与尺寸。通常第 0 级最细,索引增加图像变小、区域变粗;具体遍历可以动态升降层级,不是只朝一个方向走。

归约取 min、max 还是区间,取决于设备深度方向、算法需要的界限与保守性。Reversed-Z 下尤其不能直接照搬正向深度比较。

5. 粗糙度与降噪

简单按粗糙度模糊锐利结果,可以改善外观,但不等于按微表面 BRDF 正确积分。更完整的方法涉及方向采样、权重、像素足迹与重建,并要处理深度边缘。

随机抖动可以把带状误差转成噪声。Halton 序列、Dither 与其他采样模式有不同定义,不能把“Halftone”当作所有时域抖动的统称。

时域累积需要运动重投影、历史有效性、深度/法线拒绝与亮度约束。仅保留一张 HistoryTex 直接平均,会在遮挡变化和运动反射中拖影。

6. 命中失败要有明确回退

屏幕边缘、背向表面、离屏对象与被遮住的颜色会导致失败。应结合反射探针或其他方案,并用可信度平滑过渡,避免反射在边界突然截断。

屏幕空间覆盖与射线范围的原记录示意

优化可以从反射 Mask、降分辨率、步数预算与分层遍历入手。比较时应保留命中率与稳定性,不能只报告省了多少采样却忽略反射缺失。

总结

SSR 是在有限屏幕数据上做射线查询。正确空间、透视插值与深度界限决定命中是否可信,回退与时域处理决定最终是否稳定;Hi-Z 提供加速机会,不替代这些前提。

参考资料