Skip to content

【RFC】Support SSAO #2726

@hhhhkrx

Description

@hhhhkrx

RFC:屏幕空间环境光遮蔽(SSAO)

背景

屏幕空间环境光遮蔽(SSAO)是一种在屏幕空间计算近似环境光遮蔽的后处理技术,能够在实时渲染中增加场景的深度感与细节层次。

现状

  • 空间层次感不足:场景中的物体缺乏环境光遮蔽,导致模型交界处(如墙角、物体接触区域)缺少间接阴影,整体视觉效果显得“扁平”。
  • 间接阴影缺失:复杂模型的细节(如凹槽、缝隙)无法通过现有光照模型充分表现,影响场景真实感。

目标

  1. 在渲染流程中插入 SSAO 模块,作为标准后处理步骤之一
  2. 支持用户配置以下参数:
    • 采样数量(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 Opaquedepth模式下就必须插入一个 Depth Prepass 去获取 Scene Depth Depth Normals,当开启 After Opaque ,可以复用不透明阶段的深度和法线,不会再单独走一个Depth Prepass
  • After Opaquedepth 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

normal pass:
Image

Reconstruct normal:
Image

  • unity normal 效果对比
  • urp 中从 normal pass 到 ssao pass 时,depth texture 和 normal texture 分开两张纹理输入
Image

🔎 结论:直接通过 depth 重建 normal,节省 Pass 成本,适合移动端。

Noise

类型 引擎 特点
Blue Noise Unity 分布均匀,动态ssao
Interleaved Gradient Unity, Filament 易实现,实现静态ssao
  • Blue Noise 需要通过一张 texture2D 去存储预生成好的noise,会增加一张纹理开销,且每一帧会实时更新,并且看下来 urp 管线中只有 ssao 用到
Image
  • 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下设置的效果是可以叠加的

整体结论

渲染流程设计(引擎侧)

  1. Depth Pass(Opaque阶段产出):

    • 输入 cameraDepthTexture
    • 输出 Color Buffer
  2. 🈚️ SSAO Pass

    • 输入:depthTexturenormal(重建或采样)
    • 输出:SSAO Map
  3. 🈚️ SSAO Blur Pass

    • 输入:SSAO Map
    • 输出:平滑的 AO 结果
  4. PostProcess Pass

    • 包括 Bloom、ToneMapping 等,最终合成输出.....

配置(编辑器侧)

  • 位置:将参数暴露于Global PostProcess 设置中,作为后处理的一部分
  • 独立性:是否支持独立开启 SSAO,不依赖全局后处理开关

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requesthigh priorityHigh priority issuerenderingRendering related functions

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions