SSAO与HBAO学习笔记(持续改进)

本文详细介绍了实时渲染中的环境光遮蔽技术,包括SSAO(屏幕空间环境光遮蔽)和HBAO(半球形空间环境光遮蔽)的实现原理。SSAO依赖于深度图和法线贴图,通过在单位半球面上随机采样计算遮蔽值。HBAO则采用更智能的采样策略,考虑了采样点的几何信息。文章还提供了GPU上的伪随机数生成方法,并给出了简单的实现代码链接。最后,讨论了降噪方法,包括水平和垂直模糊以及潜在的时间一致性方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

环境光遮蔽是计算场景中每一点是如何接受环境光的。而实时渲染中的环境光遮蔽则是对此的模拟。

我们这里实现比较常见的SSAO和HBAO,一个表面点的AO的计算则是对其法线所在半球面的可见性的积分
A p ˉ = 1 π ∫ Ω V p ˉ , ω ^ ( n ^ ⋅ ω ^ )   d ⁡ ω \displaystyle A_{\bar {p}}={\frac {1}{\pi }}\int _{\Omega }V_{{\bar {p}},{\hat {\omega }}}({\hat {n}}\cdot {\hat {\omega }})\,\operatorname {d} \omega Apˉ=π1ΩVpˉ,ω^(n^ω^)dω
实时计算的时候离散的积分就好了

SSAO

SSAO的原理比较简单,其流程比较适合DeferredLighting,一个点的
其实现步骤如下

  1. 获取到当前帧的深度图Depth,能获取到法线贴图Normal更好,不能的话直接用ddx和ddy计算也行
  2. 对深度图上的每个像素,计算出其ViewSpace的坐标P0,在其法线所在半球面上采样点N个点,计算出这些点的ViewSpace坐标P1 ~ PN,并再次计算出P1 ~ PN的NDC,并采样得到这些点的真实深度值,并重建出真实的ViewSpace坐标V1 ~ VN
  3. 对于P1 ~ PN与V1 ~ VN的大小,当V大于P的时候,该点被遮挡,可以根据遮挡的距离给出遮蔽的遮挡积分的权重
  4. 最后对所有的采样点都做了遮挡计算后平均,得到当前点的AO值

实现上我们是直接抄的Unity实现版本,从中比较有意思的点是GPU上的伪随机,因为我们需要在单位半球面上随机采样

//From  Next Generation Post Processing in Call of Duty: Advanced Warfare [Jimenez 2014]
// http://advances.realtimerendering.com/s2014/index.html
float InterleavedGradientNoise(float2 pixCoord, int frameCount)
{
    const float3 magic = float3(0.06711056f, 0.00583715f, 52.9829189f);
    float2 frameMagicScale = float2(2.083f, 4.867f);
    pixCoord += frameCount * frameMagicScale;
    return frac(magic.z * frac(dot(pixCoord, magic.xy)));
}

// Pseudo random number generator with 2D coordinates
float UVRandom(float u, float v)
{
    float f = dot(float2(12.9898, 78.233), float2(u, v));
    return frac(43758.5453 * sin(f));
}

这基本是在GPU上能找到的比较好用的随机数生成方法了

SSAO实现参数没调

HBAO

相比于SSAO,HBAO则是扩展了采样点的启发性,参考[2],

环境光遮蔽的半径定义在ViewSpace,我们实现中也是

  1. 获取到当前帧的深度图Depth,能获取到法线贴图Normal更好,不能的话直接用ddx和ddy计算也行
  2. 对深度图上的每个像素,计算出其ViewSpace的坐标P0,在其法线所在半球面上采样点
    1. 当前点Tangent-Bitagent平面上随机朝着比如4个方向采样
    2. 当前点Tagent-Normal的随机一个方向上做类似RayMatching的操作,第一步还做一个随机的Offset,每个步进,都获取到对应深度的ViewSpace上的点,计算每个采样 S 1 S_{1} S1 的权重,总权重 WAO=0
      • A O ( S 1 ) = sin ⁡ Θ ( S 1 ) − sin ⁡ t AO(S_{1})=\sin\Theta(S_{1})-\sin t AO(S1)=sinΘ(S1)sint
      • W A O + = W ( S 1 ) A O ( S 1 ) WAO+=W(S_{1})AO(S_{1}) WAO+=W(S1)AO(S1)
  3. 最后把所有采样得到的权重跟采样次数平均一下就可以得到最终的AO效果

HBAO实现有噪声没弄明白

具体详细的流程还是把PPT上的内容抄一遍比较好。

实现中我们采用了跟SSAO一样的伪随机函数

一般AO的实现后都使用Horizontal和Vertical的Blur进行降噪。

还没有尝试过Temporal的方式去降噪,因为AO本来就是低频的信息,所以非常适合这种Temporal的方法

有兴趣的小伙伴可以看看我的简单实现 https://gitee.com/alienity/SRPAmbientOcclusion

引用

[1] https://zhuanlan.zhihu.com/p/46633896

[2] https://developer.download.nvidia.cn/presentations/2008/SIGGRAPH/HBAO_SIG08b.pdf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值