环境光遮蔽(AO)技术,用于模拟场景中的光照,使场景中的物体看起来更加真实。
简介
- 随着设备的更新换代,现代游戏玩家对画面质量的要求越来越高,全局光照成为提升游戏视觉效果的关键技术。全局光照技术基于物理光学原理,通过计算光线在场景中的反射、折射和散射等过程,模拟真实世界的光照效果,使得游戏场景看起来更加逼真。然而,这种真实带来的代价就是计算成本过高,离线生成一个静态场景的效果可能需要花上几个小时,并不适用于实时渲染。因此,需要通过简单但在视觉上仍然令人信服的解决方案的进行替代,一种基本的全局照明效果是环境光遮蔽(Ambient Occlusion)。
基础概念
立体角(Solid Angle)
- 平面角定义为角所对的弧长
s与半径r的比值,用ω表示。
- 立体角(Solid Angle)则是在三维空间下的角度,其所对的面积
A与半径r的平方的比值,用Ω表示。
- 立体角通过
θ和φ两个角度来表示,其中θ是与z轴的夹角,φ是与x轴或y轴的夹角。
- 如图所示,对于单位立体角
dΩ(即dθ和dφ),其所对的面积A即为矩形 ABCD(近似)的面积,即
其中,AB 为 dθ对应的弧长,CD 为dφ对应的弧长,则有
因此
辐射能量(Radiant Energy)
- 辐射能量(Radiant Energy)是指电磁辐射的能量,用
Q表示。
辐射通量(Radiant Flux)
- 辐射通量(Radiant Flux)是指单位时间内的辐射能量,用
Φ表示。
其中,Q是辐射能量,t是时间。
辐射强度(Radiant Intensity)
- 辐射强度(Intensity)是指单位立体角内的辐射通量(所有面积光总和),用
I表示。
其中,Φ是总辐射通量,Ω是立体角。
辐照度(Irradiance)
- 辐照度(Irradiance)是指单位面积上接收到的辐射通量(所有立体角方向总和),用
E表示。
其中,Φ是总辐射通量,A是接收面积。
辐射率(Radiance)
- 辐射率(Radiance)是指单位立体角,在单位面积上辐射通量,用
L表示。
其中,Φ是总辐射通量,Ω是立体角,A是接收或光源面积,对应入射或出射辐射率。基于理想漫反射表面(Lambert 表面),只有垂直于光的投影面积,才是真正的辐射面积,所以辐射率最终需要对面积进行修正,即A cosθ。 - 由于总辐射通量是所有面积所有方向的辐射通量总和,所以需要对立体角和面积进行二次微分。
渲染方程(Rendering Equation)
- 渲染方程(Rendering Equation)是全局光照模型中的基本方程,用于描述光在场景中的传播和反射。渲染方程的基本形式为:
其中,p为观察的物体表面位置,v为观察方向,l为光的入射方向,n为物体表面法线,n · l表示入射光被物体表面接收(和投影面垂直)的比例,f为物体表面反射率(接收到的光反射到观察方向的比例)。
环境光遮蔽(Ambient Occlusion)
- 为了实现全局光照模型效果,则需要求解渲染方程,常用的方法有两种,即有限元方法和蒙特卡洛方法。其中,光能传递是基于有限元方法的算法,各种形式的光线追踪则是使用蒙特卡洛方法。然而,这些方法虽然可以产生较好的效果,但生成一帧图像可能需要花费数个小时,并不适用与动态场景。
- 为了将全局光照效果应用到计算生成的场景中,需要使用一些简化的模型方法,一种基本的方法是环境光遮蔽(Ambient Occlusion,AO)。为了简化,假设两个条件:
- 物体表面为 Lambert 表面。
- 入射辐射率在各个方向上都为相同的常量
L'。
- 根据前面的辐射率公式,可以得到辐照度
E为
- 然而,当前辐照度并未考虑可见性,即某些方向的光可能被场景中其他物体或自身某些部分阻挡,则这些方向的入射辐射度不为
L'。假设来自被遮挡方向的入射辐射度为 0 ,未被遮挡方向的入射辐射度为 1,则
其中,v为可见性函数,L'后的积分部分为环境光遮蔽因子,用k表示,即
- 当所有方向都没有遮挡时,
v为 1 ,此时k有最大值。当所有方向都被遮挡时,v为 0 ,此时k有最小值。
- 因此,归一化的环境光遮蔽因子
k'为
辐照度 E为
- 通过环境光遮蔽方法计算全局光照效果,最终会转换为通过计算环境遮挡因子实现。计算环境遮挡因子可能很耗时,通常需要执行在渲染之前离线进行。预先计算任何与光照相关的过程,包括环境遮挡在内的信息,通常被称为烘焙。预计算环境光遮挡最常见的方法是通过蒙特卡洛方法,即在法线周围的半球面上,均匀地随机取 N 个方向,并沿着这些方向追踪光线,检查这些方向最终是否可见,对结果求平均值,即为
k'的估算值,则能计算出对应的辐照度。
屏幕空间环境光遮蔽(Screen Space Ambient Occlusion)
- 计算环境遮挡因子的离线方法,能得到较好的表现效果,但需要进行光线追踪计算,计算成本较高,且仅适用于静态场景。对于实时动态场景,需要使用更加简化的模型,避免大部分此类计算。对于动态场景,可以通过将物体进行分组后,再用简化模型替代每一组,之后计算每一个简化模型的 SDF 信息,就能通过锥体追踪得到光线的遮挡信息。
- 然而,在物体空间下进行计算的方法,随着场景复杂度的提升,计算量会越来越大,造成新的性能压力。事实上,关于遮挡的一些信息可以完全从屏幕空间数据中推断出来,如:深度、法线,这些数据在渲染过程中已经生成。屏幕空间下计算的方法,不受场景复杂度的影响,而是仅和渲染过程使用的分辨率相关,因此具有恒定的计算成本。
- 屏幕空间下的环境光遮蔽(Screen Space Ambient Occlusion,SSAO),通过使用 z-buffer 深度缓冲区作为唯一输入,来估算每个像素的环境遮挡因子。在以像素位置为圆心的球面上,随机取一组采样点,进行深度测试,最终通过深度测试的样本数量占比即为环境遮挡因子。
- 如图所示,相机在正上方,黄色点为当前计算的像素位置点,其余点为采样点,分布在以黄色点为圆心的球面上。其中,红色点在物体内部,即未通过深度测试,而蓝色点虽然在物体外部,但在相机方向上被遮挡,即同样未通过深度测试,仅绿色点能通过深度测试,因此环境遮挡因子
k'为 0.2 。 - 其中,样本的选取,不是只考虑位于表面上方半球内的位置,而是包括了物体内部的位置。在这种采样方式下,会出现一个平坦的表面会变暗,且边缘比周围更亮的情况。尽管如此,这种表现结果通常在视觉上依然能令人满意。