SSAO,屏幕空间环境光遮挡概述和细节讨论

小明 2011-11-15 2,979 views

SSAO,屏幕空间环境光遮挡概述和细节讨论

屏幕空间环境遮挡(SSAO)是Crytek最早采用的一种间接光照技术,这种技术使被遮蔽的部分看起来更暗一些。遮蔽可以看成这样一种现象,比如连接门的折页相当于两个平面,当这两个平面呈180度打开时,光照到他们上面相当于一个平面,这是光在每个点上的反射都基本相同,当他们呈90度时,靠近折缝处的点有部分被另外一面遮住了光线的反射路径,当极端情况,两面相对合十的时候,光线没办反反射出去,变成全黑。

为了模拟这种光学现象,同时达到足够的效率,Crytek的做法是通过一个采样球在屏幕空间采样若干个深度值,比对采样半径是否比空间几何体的深度值大来判定采样点是否处于遮蔽体内。通过累加这若干个采样点的遮蔽与否来判定这个点有多少比例被照亮。详细算法参考ShaderX7.

为了得到深度值,需要z信息。Zbuffer在dx9中取不到,而且非线性分布也限制了其精确性,所以大多数ssao算法都是把几何信息转换到摄像机空间然后渲染到纹理中的,所以我也这么干。为了能在以后有时间做延迟渲染,我把它组织成gbuffer的形式,两张纹理,一张存ambient,一张存normal+depth。深度是摄像机空间的z值除以视锥长度,这样depth是0-1的规格化范围。关于gbuffer的分配,这边其实可以展开,大致想了一下2张4通道32位纹理可以存储足够的信息完成光照模型,一张存ambient,占3个通道,剩下一个通道存漫反射的rgb,到时候shader中解压。另外一张2个通道存normal,一个通道存depth,剩下一个通道存自发光的rgb。不过,ssao只用深度和法线就够了,至于法线的作用,过会说。

 

这个就是gbuffer

 

这个是ssao结果

由于采样点不够多,会产生下面的噪点,图中的小点点就是噪点

 

为了消除噪点,Crytek上面说使用4*4的权值相同的滤镜就可以了,但是可以看到,应用这种滤镜会使画面变得模糊,尤其是远处的场景,由于那里相邻像素之间的实际空间距离比较大,如果单纯的做均值平滑处理,很容易丢失细节。

 

为了达到更好地保留细节的效果,使用名为smartbox的滤镜,它是一种权值自适应的滤镜,它会读取深度值,对于深度值与原始点相差大地像素,它的权值会比较小。这样,远处像素的细节丢失不会太严重,因为相差很大的两个像素对于中心点的影响相应的减小,下图为实际效果

 

最后,再读取normal map计算光照,把光照结果和ssao叠加后就形成如下的最终效果

 

左边为ssao开启,右边为ssao关闭,注意强封处的阴影和台阶上的阴影效果

 

Ssao开启

 

Ssao关闭

 

自遮蔽。

关于normalssao中的作用,我想根据我的理解来解释一下自遮蔽这种现象。

 

如图,有一面面向摄像机的墙和一面斜插入屏幕的墙,如果按照Crytek的算法,对于面向我们的墙,我们随机地取采样球内部的一些点作为采样向量,大概有一半在点在墙内,一半在墙外,墙看起来是亮的,但对于斜着的这面墙,我们随机生成了一个采样点,这个点是摄像机空间的点,当我们把它转化成屏幕空间的时候,由于墙是斜着的,相当于三角形的斜边,对于采样点来说,它在屏幕空间的坐标与原始点的变化比是非常小的,考虑如果这个墙非常斜,接近垂直屏幕,那么采样点在z方向上无论如何变,它都不会越过屏幕空间的一个像素,也就是说大多数点转化到屏幕空间以后它都和采样球的中心点没变化,采样点的深度值等于原始点的深度,那么他们都被认为是采样点落在了墙壁里面,所以这面墙大多数点都是被遮蔽的点,变得很黑。不知道把你说糊涂了没。

为了解决上面的问题,把采样球沿着法线方向偏移一下,这时,采样球离墙壁远了一点点,而这样一来,采样点能取到的点的范围更大,而且大部分采样点不会再陷入墙壁内了,这时,斜对摄像机的墙壁就不会发生错误的自遮蔽现象了。

优化

关于优化,Crytek提到了几点,有印象的是

1. 降低深度图的尺寸

2. 向量化指令

关于1没什么好说的,向量化代码确实能够减少一些gpu代码的生成,详细请看geek3d网站的一片文章。另外我曾经试图去掉采样随机纹理,而转向使用常量寄存器存储这些随机数,以图减少纹理查询的开销,谁知事与愿违,产生了上篇文章出现的现象。

最近战地出新作了,其中一项改进是使用了HBAO,Horizon Based Ambient Occlusion,对于这种技术,我正在看论文,从Horizon Map看起比较好,因为如果你不理解这个的话直接看HBAO是不能够融会贯通的,对于Horizon Map本来是为了解决凹凸贴图无法产生自阴影的,它通过在法线方向上记录某一方向某个高度是否会产生遮蔽来存储遮蔽图,这种方式更贴近光学实质,我觉得拿来练练手很不错

    一块砖头已落地!


    欢迎拍砖!