实时渲染-08:屏幕空间反射
反射路径
屏幕空间反射 Screen-Space Reflection,SSR 使用当前相机的深度、法线和照明图,查询反射方向上遇到的表面,再从该表面取得光照。其核心更接近屏幕空间射线追踪:先求交,后着色;“反射”是它常见的用途,并不限制其只能处理理想镜面。

左图地面能看到机械臂和周围结构的反射,右图只剩原来的地面着色。机械臂先被光源照亮,再向地面反射光,最后地面将其反射到相机,这是一条间接光照路径。
SSDO 在局部范围内粗略收集方向贡献,SSR 则沿选定方向在深度壳上搜索交点。两者都复用相机信息,但查询路径和质量目标不同;不能把 SSAO 的球内深度失败率直接当成 SSR 的反射颜色。
镜面查询
给定表面位置 、单位法线 和从表面指向相机的单位方向 ,镜面反射方向为
从 沿 找到交点 ,取得 向 的出射辐亮度,再按接收材质的反射比例合成。GLSL 中反射函数的输入是传播到表面的方向,所以使用 reflect(-v, n)。

地面每个片元的射线命中不同旗帜位置,便读取相应颜色,形成倒置的空间结构。深度图只提供相机最近可见层,尚不能保证这些交点与完整场景的真实反射交点相同。
理想镜面方向集中,一次查询就能得到主要路径。粗糙材质的反射瓣有宽度,需要在其范围内采多个方向;越接近漫反射,方向范围越大,低样本的噪声与漏检也越明显。因此 SSR 通常更适合镜面或较集中的 Glossy 反射。
射线投影
在一致的视图空间中写射线
位置、法线和观察向量不能混用世界与视图空间。表面起点需适当偏移或忽略起点附近区间,避免马上命中自身。
用当前投影矩阵 得到裁剪坐标 ,再做齐次除法 ,将 经视口变换转为像素位置。深度比较同样需要统一约定:可以比较同一投影后的深度,也可以将深度图反建为正的视图距离。
透视除法使等距离的三维步长在屏幕上并不等长。若沿屏幕直线逐像素步进,视图空间属性仍要按透视正确方式恢复;不能将投影端点的视图深度做普通线性插值。射线越过近裁剪面之前,应先裁剪有效区间,避免齐次除法在 附近发散。
线性步进
Ray Marching 沿射线取样本,在每步将样本投影到屏幕并读取深度。射线深度从可见表面前方变到后方时,可能穿过了深度壳。

黄色点为起点,橙色点为沿射线的测试点,绿色点示意找到的交点;弯曲黑线代表几何截面。步长太大可能跨过薄结构,太小则在长空区反复取样。
深度图只有一层表面,并没有体积厚度。实现常给表面一个有限的深度容差 ,将 当成可命中的深度壳。 太小容易漏掉交点,太大会把与真实表面相距较远的射线也接纳,甚至错误命中后方自由空间。
发现跨越后,可以在前后两步之间回退、二分或细步搜索,提高交点位置精度。细化只改善已找到区间的定位,不能补回粗步已经跳过却没有发现的物体。
1 | // 概念版线性查询,所有 depth 使用同一正视图距离约定。 |
边界、背景深度、射线朝向、法线朝向与厚度都影响最终判断。这是对屏幕深度壳求交的近似,不是对真实三角网格求交。
深度层级
为了减少空区查询,建立层级深度 Hierarchical Z,Hi-Z。以正视图深度、较小值靠近相机为例,父格记录子区域的最小值:

底层覆盖原始像素,上层单个纹素覆盖更大屏幕区域,直到极粗的层。它们不是用于模糊着色的普通 mip;构造操作必须保留遮挡的保守界。
若射线在当前格内部的整个区间都满足 ,则比该格所有表面更靠近相机,可以安全跨到格子的出口。普通平均值可能大于最近表面的深度,导致射线越过最近物体时还被误认为在“平均表面”之前。

图中白线是深度曲线,蓝色块是各层对一段区域的界。较粗的界可能包括很多空区域,但不能漏掉其子区域的表面;红射线不碰到粗界的区间,才可以整段跳过。其逻辑与 BVH 使用包围盒拒绝一组几何相似。
保守跳过需要检查射线在该格内部的区间,不能只比较格子入口处一个点。层级查询也应使用对应格的界,双线性插值几个父格会破坏原来的保守含义。
采用 Reverse-Z 时,“更近”的深度数值更大,应使用相应的最大值界与反向比较。无论哪种约定,算法依据都是最近表面的保守界。
层级遍历
课程用 Stackless Ray Walk 描述不显式维护遍历栈的访问方式:在确定没有命中的区域尝试更粗层,一次跨过更多像素;出现潜在交点时回到细层检查。

从左侧相机到下方表面是相机可见路径,之后向上的是反射路径。水平线划分屏幕区域,白线为可见深度壳;反射射线经过的空区可以用较粗格跳过,靠近白线时需要较细的检查。
课件简化逻辑是 above Z plane -> level++、below Z plane -> level--。其中层数增加表示查询更粗范围,不表示射线离场景更近。源伪代码省略了起点、格边界、步进回退和终止条件,实际实现可以写成以下更完整的概念流程:
1 | // 在每格内部取射线区间,潜在相交时不跨过未经检查的细格。 |
粗格按 个像素对齐。起点位于中间、射线刚好落在边界或反方向跨格时,应选择射线实际进入的子格,不能简单将步长加倍而忽略对齐。小的边界偏移可避免反复查询同一格;偏移太大也会跳过几何。层级只改变访问效率,不能改变射线方向或把潜在交点直接当成命中。
交点着色
求交确定当前方向的来源 ,之后仍按渲染方程计算:
命中方向上的 由 提供。当前相机颜色记录的是 朝相机的结果,若把它用于朝 的出射方向,通常需要将次级反射源近似为 Lambertian。源是 Glossy 时,两方向可能看到完全不同的高光,因此读取同一个屏幕颜色会有方向误差。
输入宜为线性 HDR 的直接照明或明确允许复用的照明层。读取最终 Tone Mapping、UI 叠加后的颜色不符合辐亮度积分;把已经含 SSR 的最终图再作为同帧 SSR 来源,还可能重复反馈反射。接收表面自身的 BRDF 与 Fresnel 权重也不能省去。
沿光线的辐亮度不需要再乘 。这里以方向积分,面积到立体角的关系隐含在“某块表面占了多少采样方向”中;若改为对面片面积采样,才显式出现两个余弦与平方距离几何项。两种参数化不能重复计入。
射线的第一个有效交点同时回答了该近似路径上“哪块表面可见”。因此不需要为每个命中点另生成一张 VPL 阴影图,但这个可见性只针对当前屏幕深度壳。
粗糙反射

怪物脚边的反射相对紧凑,更远位置的反射范围变宽,表面局部法线也改变了反射结构。课程用同一场景逐项展示四个目标:锐利与模糊反射、接触硬化、掠射拉长、逐像素粗糙度与法线。
接触硬化 Contact Hardening 在这里指靠近被反射物体时更清晰、远离时更分散。具有固定角宽的反射瓣,沿空间传播时足迹随距离扩大,这与把整幅镜像用相同半径模糊不同。
高光拉长 Specular Elongation 描述掠射观察时反射分布的拉伸。即使微面分布是各向同性,投影和方向几何也能形成拉长的屏幕结果,不能直接认定为各向异性材质。
各像素可以有不同粗糙度与法线,因此方向采样和过滤足迹也不同。若从概率密度 采方向,估计为
BRDF Importance Sampling 将样本集中到高贡献反射瓣内,提高有限预算的利用率。未命中屏幕信息的方向应明确用零或其他光照表示作 fallback;将其随意删掉再按命中数平均,会改变估计的能量。
复用与过滤
邻近接收点的反射路径可能相似,可以进行 Hit-Point Reuse,重用已经找到的交点,减少重复查询。但交点对于新接收点的方向、几何关系和 BRDF 权重不同,还要核对可见性与采样分布;邻像素颜色直接复制不是正确的样本复用。
另一优化是 Prefiltered Samples:预过滤交点颜色或照明,再按接收反射瓣的足迹选择尺度与权重。高粗糙度的方向范围更宽,但实际屏幕足迹还取决于交点距离和投影,不能仅按粗糙度给整幅图一个固定模糊宽度。
深度断层附近,普通颜色 mip 会混合前景与背景。联合双边等保边过滤利用深度、法线限制混合,可减轻这类污染。时间累积还可以复用前帧样本,但需要运动对应与历史有效性检查;这些步骤属于后续低采样重建的内容。
屏幕限制

反射可能需要手掌内侧、背面或被手指挡住的几何,当前图像却只记录相机看见的表面。加密步进或提高深度层级精度,都不能补出不存在的输入。

地面某些方向的射线离开视口,旗帜反射随之硬截断。将边缘或距离较大的贡献逐渐降低,可以缓和断层。

渐隐后的交界更连续,但正确反射并未恢复。实用管线可以在 SSR 缺失时混合环境探针、体素或真实射线查询,权重应避免重复计光并保持连续。
SSR 不直接累加一组近距离点源,因而避开了基础 VPL 方法的一些尖峰与逐源遮挡开销;它仍可能产生采样噪声、错误深度命中、漏反射和时间伪影。优势主要来自镜面方向集中、相机数据可复用;接近漫反射时,大范围方向采样和屏幕缺失使这种优势减弱。


