🗒️Ambient Occlusion
type
status
date
slug
summary
tags
category
icon
password
AO定义
AO全称Ambient Occlusion,即环境光遮蔽。用来加深场景的遮蔽效果,也就是加深阴影的效果。AO的实现可以更加真实的反应模拟世界中的能量守恒,被广泛用到游戏中。
经典的AO定义如下:
这个公式基于辐射度量学,满足能量守恒,用这个公式计算的AO在效果上是最佳的。
是位于表面的某点,是点的法向量,是在半球面内的立体角,是点的可见度函数:
因为和都是单位向量,令,这个积分可以化简为:
因此,的含义就是点在半球面内的遮蔽程度,可以证明:
其中。
因此,越接近1,那么的遮蔽程度越大。
传统的AO计算方法采用光线追踪算法。光线追踪算法的好处就是效果很好,因为是直接计算积分,满足能量守恒。
但是这种方法不适合游戏中,因为太慢了,所以就有了下面的计算近似AO的算法(强调一下,是近似AO)。
SSAO
SSAO是一种基于延迟渲染,在屏幕空间下计算的AO算法。这个AO算法本质上就是在屏幕空间下进行类似积分的运算,但是还是有一些差别。
原理当然需要用到G-Buffer,在获得四张贴图——位置(可选)、法线、环境光、深度之后,在屏幕空间中,进行SSAO的计算。
首先是获得AO贴图,AO贴图是一种灰度图,如下:
可以看出,有强烈的遮蔽信息。所以我们需要先生成这样的AO贴图。这就是所有AO算法需要实现的一点。但是传统的光线追踪需要大量的三角形求交,所以不适合在游戏中应用。这就为什么SSAO出现了,SSAO在屏幕空间中进行遮蔽计算。
如何获得AO呢?在屏幕空间中,首先遍历像素点,在像素点所在的世界空间坐标的法线方向半球面内随机的选取采样点,然后对这些采样点进行深度测试。也就是判断这些采样点是否被遮蔽,如果被遮蔽了,就计数加1. 最后算出被遮蔽的采样点和总采样点的比值,这个比值是永远小于1的。然后存入到贴图中。这样就能得到AO贴图了。
在后处理中,我们可以对这个AO贴图采样,得到的数值,作为Phong光照中ambient分量的参数:
怎么随机采样?
定义一个核函数,矩阵大小可以是8*8(假设),每个元素都是一个在切线空间的三维向量,表示的是xyz三个方向的随机采样点:
取值范围为[-1, 1], [-1, 1], [0, 1],为什么要这样?因为我们是在屏幕空间里计算,而z轴在屏幕空间的取值范围就是0到1,其他的事-1到1.
为什么要定义在切线空间,试想一下,如果不依赖这样的核函数,那么我们对每个得到的顶点,都要在法线方向上进行核函数的生成,然后得到随机的采样点,性能差而且效果也和原本的差不多。所以最好的方法还是定义一个固定的随机核函数,然后对每个采样后的顶点进行切线空间到观察空间的变换即可,然后就能直接得到随机的采样点了。下面是计算AO的过程:
综上所述,SSAO采用了如下的近似: