-
-
Notifications
You must be signed in to change notification settings - Fork 357
Open
Labels
enhancementNew feature or requestNew feature or requesthigh priorityHigh priority issueHigh priority issuerenderingRendering related functionsRendering related functions
Milestone
Description
RFC:屏幕空间环境光遮蔽(SSAO)
背景
屏幕空间环境光遮蔽(SSAO)是一种在屏幕空间计算近似环境光遮蔽的后处理技术,能够在实时渲染中增加场景的深度感与细节层次。
现状
- 空间层次感不足:场景中的物体缺乏环境光遮蔽,导致模型交界处(如墙角、物体接触区域)缺少间接阴影,整体视觉效果显得“扁平”。
- 间接阴影缺失:复杂模型的细节(如凹槽、缝隙)无法通过现有光照模型充分表现,影响场景真实感。
目标
- 在渲染流程中插入 SSAO 模块,作为标准后处理步骤之一
- 支持用户配置以下参数:
- ✅ 采样数量(Sample Count):控制 SSAO 采样的精度
- ✅ AO 半径(Radius / Distance):控制遮蔽计算的范围
- ✅ 模糊强度(Blur Kernel Size / Strength):控制 SSAO 的模糊效果,减少噪声
- ✅ 强度系数(AO Intensity):控制 SSAO 效果的整体强度
对比分析
特性 | Unity URP | Filament |
---|---|---|
启用方式 | RenderPipelineAsset 设置 + AfterOpaque | 后处理链一部分(依赖 PostProcessManager) |
是否支持 SpecularAO | ❌ 不支持 | ✅ 支持,间接光阶段混合,使用aoBentNormal |
Normal 来源 | 可选 Normal Pass 或深度重建 | 深度重建 |
Noise 类型 | Blue Noise + Interleaved | Interleaved |
sample count | unity中叫Samples ,高中低三种可选 |
通过 QualityLevel 枚举:LOW/MEDIUM/HIGH/ULTRA |
Blur 模式 | 多种选择(Gaussian、Bilateral、Kawase) | Bilateral |
两个引擎设计的不同衍生的问题
After Opaque 的意义
- 如果不开
After Opaque
在depth
模式下就必须插入一个Depth Prepass
去获取Scene Depth
或Depth Normals
,当开启After Opaque
,可以复用不透明阶段的深度和法线,不会再单独走一个Depth Prepass
After Opaque
在depth normal
下,交换了opaque pass
和ssao
的顺序,opaque 在 ssao 之后的话颜色会更深点
为什么和 Specular AO 混合
- Filament 将 SSAO 与 SpecularAO 一起用于间接光阶段混合,避免高光过度明亮
- Unity URP 中未内建,但可通过自定义 shader 混合加入
本次重点在漫反射部分的屏幕空间 AO 效果,可以先不考虑高光的 AO,后续高光单独作为一个 PR
Normal 获取
方式 | 描述 |
---|---|
Reconstruct from Depth | Shader 中直接从深度图重建 View Space Normal (filament方案) (unity方案) |
DepthNormals Pass | 单独渲染一个 Normal Pass |
- unity normal 效果对比
- urp 中从 normal pass 到 ssao pass 时,depth texture 和 normal texture 分开两张纹理输入

🔎 结论:直接通过 depth 重建 normal,节省 Pass 成本,适合移动端。
Noise
类型 | 引擎 | 特点 |
---|---|---|
Blue Noise | Unity | 分布均匀,动态ssao |
Interleaved Gradient | Unity, Filament | 易实现,实现静态ssao |
Blue Noise
需要通过一张texture2D
去存储预生成好的noise,会增加一张纹理开销,且每一帧会实时更新,并且看下来 urp 管线中只有 ssao 用到

- Interleaved Gradient 是直接通过公式计算,在 shader 中动态生成,filament 中的 Dithering/SSR/TAA 都用到了
🔎 结论:效果上
Blue Noise
会更自然,考虑到性能那Interleaved Gradient
足够了,还不需要多一张纹理
模糊(Blur)
类型 | 特点 | 引擎支持 |
---|---|---|
Bilateral Blur | 保留边缘细节,质量更高 | Unity , Filament |
Gaussian Blur | 简单快速,可能模糊边缘 | Unity |
Kawase Blur | 快速近似,适合低端设备 | Unity |
- Unity URP
- Bilateral blur:三个 pass,前两个 pass 做水平+垂直处理,考虑了法线,最后一个 pass 再做细节修整
- Gaussian Blur:两个 pass,只关心像素平面(水平+垂直)偏移
- Kawase Blur:一个 pass,采样四个像素
🔎 结论:因为 blur 对性能影响最大,还是应该提供不同模糊质量设置,对比了下效果,Bilateral 和另外两者切换的时候效果会很明显,但是 Gaussian 和 Kawase 切换的时候视觉上不会有太大的变化
sample count
预设档位 | Unity URP (Samples ) |
Filament (QualityLevel ) |
说明 |
---|---|---|---|
Low | 4 | QualityLevel::LOW=7 | 合移动/低端设备,最低模糊精度 |
Medium | 8 | QualityLevel::MEDIUM=11 | 推荐桌面中档,平衡效果与性能 |
High | 12 | QualityLevel::HIGH:=16 | 适合高端平台,最平滑的遮蔽效果 |
- 越高的采样数量越密集,unity选择均匀的偶数主要是考虑对称,filament按照角度螺旋式递进采样,低质量选择奇数能避免可见条纹
编辑器配置对比
引擎 | 配置位置 | 特点 |
---|---|---|
Unreal | PostProcessVolume 内部 | 项目设置中默认打开环境光遮蔽 ,移动环境光遮蔽 默认关闭 |
Unity URP | Settings → Renderer → SSAO | 独立配置,并且不依赖 Post-processing 总开关 |
Unity HDRP | SSAO 概念上属于 Lighting | SSAO 在全局默认开启,不依赖后处理 |
- 如果场景中添加多个相机,URP 中每个
Camera
下 SSAO 都会生效,所有相机共享配置,但是不会产生叠加效果并且也没办法单独配置 - UNREAL 中每个
PostProcessVolume
都可以独立配置 SSAO,根据PostProcessVolume
顺序决定要哪个生效 - HDRP 中的 SSAO 在 Lighting 下,可以在全局默认配置中选择是否开启,但是 camera 下又能独立配置,camera的
Frame setting
可以 override 全局的默认设置,但是camera的这个Frame setting
只能选择ssao开和关,并不能单独设置参数,然后volume也可以add override
添加ssao,这里就可以修改ssao的参数配置了,全局的volume和局部的volume均能配置,局部volume的ssao是:虽然可以修改参数,但是修改的其实是“全屏ssao的参数”,走到局部的盒子里,改的是当前局部盒子里的全屏ssao效果,然后volume下设置的效果是可以叠加的
整体结论
渲染流程设计(引擎侧)
-
Depth Pass(Opaque阶段产出):
- 输入
cameraDepthTexture
- 输出 Color Buffer
- 输入
-
🈚️ SSAO Pass:
- 输入:
depthTexture
,normal
(重建或采样) - 输出:SSAO Map
- 输入:
-
🈚️ SSAO Blur Pass:
- 输入:SSAO Map
- 输出:平滑的 AO 结果
-
PostProcess Pass:
- 包括 Bloom、ToneMapping 等,最终合成输出.....
配置(编辑器侧)
- 位置:将参数暴露于
Global PostProcess
设置中,作为后处理的一部分 - 独立性:是否支持独立开启 SSAO,不依赖全局后处理开关
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requesthigh priorityHigh priority issueHigh priority issuerenderingRendering related functionsRendering related functions