屏幕空间全局光照(SSGI)
概述
屏幕空间全局光照(Screen Space Global Illumination,简称 SSGI)是一种利用屏幕空间数据模拟间接光照效果的实时技术。
它通过分析当前帧缓冲中的深度、法线和场景颜色来估算光线在表面之间的反弹,添加环境遮蔽和颜色渗透效果,从而创造更真实的光照。
与传统的**基于图像的光照(IBL)**不同,IBL 只能提供静态的环境光,而 SSGI 能够动态捕捉场景中可见几何体的光线反弹。这意味着红色的墙壁会在附近的白色表面上投射出淡红色调,明亮的物体会照亮周围环境——这些都是根据屏幕上可见的内容实时计算的。
优点
- 动态间接光照:基于表面的实际颜色和当前帧中的位置捕捉光线反弹
- 无需预烘焙:适用于完全动态的场景,不需要光照贴图烘焙或预计算
- 环境遮蔽:自然地使几何体阻挡环境光的区域变暗
- 颜色渗透:表面会从附近物体获取颜色色调,增强真实感
- 性能:与完整的光线追踪全局光照相比相对高效
局限性
- 仅限屏幕空间:只能使用当前帧中可见的信息——视野外或相机背后的物体无法贡献光照
- 几何缺失:被遮挡或屏幕外的表面不会影响结果,这可能导致相机移动时光照出现"闪烁"
- 光线距离受限:为了保持性能,追踪距离有限,因此大范围的间接光照可能不完整
- 噪声和瑕疵:该技术使用采样和近似,需要时间和空间过滤来减少噪声
- 性能开销:与静态 IBL 相比仍然计算密集,需要针对不同硬件仔细调整
启用 SSGI
SSGI 需要相机和 IBL 环境光同时允许:
ts
scene.env.light.type = 'ibl';
camera.SSGI = true;相机必须启用 HDR,SSGI 强度必须大于 0,且 IBL 必须同时提供 radiance 和 irradiance 数据。设备还必须支持可渲染的半浮点纹理、至少 2 个 draw buffers 以及 16 字节/采样的颜色附件预算。
后端差异:
- WebGPU 和 WebGL2:使用运动矢量、Hi-Z 加速、历史场景颜色和完整的时域过滤,质量更高
- WebGL1:没有运动矢量也没有 Hi-Z,退化为线性光线步进 + 纯空间过滤、单次弹射,历史仅按同像素验证 —— 噪点更明显,间接光更弱
质量档位
| 档位 | 分辨率 | 每像素光线 | 最大步数 | 去噪次数 |
|---|---|---|---|---|
quality | 全分辨率 | 2 | 64 | 3 |
balanced | 半分辨率 | 1 | 48 | 2 |
performance | 半分辨率 | 1 | 24 | 1 |
custom | 可配置 | 1–4 | 1–256 | 0–5 |
ts
camera.ssgiQualityPreset = 'quality';选择 custom 档位后可分别设置追踪分辨率、每像素采样数(SPP)、最大步数和去噪次数:
ts
camera.ssgiQualityPreset = 'custom';
camera.ssgiHalfResolution = true;
camera.ssgiRaysPerPixel = 2;
camera.ssgiMaxSteps = 48;
camera.ssgiDenoisePasses = 2;通过 API 直接修改任意自定义参数会自动将档位切换为 custom。
参数控制
| 属性 | 默认值 | 说明 |
|---|---|---|
ssgiIntensity | 0.7 | 屏幕空间间接光相对于 IBL 的强度。控制 SSGI 对最终图像的影响程度 |
ssgiSkyOcclusion | 1 | 遮挡几何体阻挡环境光的程度。1 为完整的物理遮蔽;降低该值会减少变暗效果 |
ssgiMaxDistance | 32 | 视空间最大追踪距离。更大的值可以捕捉更远的光线反弹,但性能开销更高 |
ssgiThickness | 0.5 | 光线命中的深度相交厚度 |
ssgiStride | 1 | 线性光线步进的像素步长(仅 WebGL1) |
ssgiMaxRayIntensity | 10 | 限制过亮采样以减少萤火虫瑕疵 |
ssgiTemporal | true | 是否启用时域累积以减少噪声 |
ssgiTemporalWeight | 0.94 | 历史稳定后时域过滤的最大历史帧权重 |
ssgiDepthReject | 0.5 | 拒绝无效时域重投影的深度阈值 |
ssgiNormalReject | 0.75 | 时域重投影的法线相似度阈值 |
性能优化建议
- 从
balanced档位开始,然后根据需要调整 - 使用半分辨率(
ssgiHalfResolution = true)可以显著提升性能,视觉损失极小 - 在 WebGPU 和 WebGL2 上 SSGI 会自行申请 Hi-Z 金字塔,光线追踪已经是加速的
- 如果有强时域过滤,可以降低
ssgiRaysPerPixel - 在几何体简单或深度复杂度有限的场景中降低
ssgiMaxSteps