直观理解SSAO原理

SSAO ,screen space ambient occlusion  屏幕空间环境光遮蔽。

一般光照模型中,环境光用于模拟光线的二次散射,从而使得不受直接光照的地方也能有相应的亮度。

很明显,犄角旮旯里,不应该有太多的光被散射出来,所以犄角旮旯和露出表面的环境光不应该相同。

而在光照模型中,环境光是一个定值。

所以ssao出现了,他解决的就是 如何定量犄角旮旯应该吸收(二次散射不出去的光自然大部分都被物体吸收)多少环境光的问题。

算法的核心其实相当直观,问题来自光的二次散射,那就来为每一个片元模拟一个随机的光线散射模型。

直观理解SSAO原理_第1张图片直观理解SSAO原理_第2张图片

ssao算法基于屏幕后处理,或者说直接对接延迟渲染。因为需要对每一个片元都运行一次算法,消耗巨大。前向渲染根本无法使用。其次,ssao算法 被插在  Gbuffer pass之后   正式渲染之前。它的输出也是一张数据纹理(记录着每个片元受多少环境光)。正式渲染时,仅仅只需要在应用环境光的时候乘上ssao纹理中的数据即可。另外,为了方便基于视口的深度比对,Gbuffer的输出包括光照计算会转变到观察空间下进行,而不是世界空间。

如图所示,图中橘红色的点表示正在处理的片元,蓝色的小点表示随机的向量点,且分布在法向量半球里。算法的核心思想就是得到一个衡量所有蓝点中 究竟有多少点在紫色平面下的值(比值...)。紫色平面是什么? 他就是在gbufferPass中,深度测试赢了的那些片元(橘红色的点也是)。算法通过比较蓝色小点在观察空间中的z值和gbuffer中相印uv坐标中对应的z值,如果蓝点比‘紫点’深,就增加这个片元被遮蔽的因子。(所以你应该知道为什么不用整球了,用整球的话,平坦的墙壁也会灰蒙蒙的,除非你想要这个效果)。很明显左图中的橘红色点周围是平坦的表面,蓝点全部在紫点之上,所以它不会有任何遮蔽因子。右图,橘红色点被两个平面夹住了,显然会有很多蓝色的点处于紫点之下,所以它的遮蔽因子就会比较多。

整体逻辑就是这样,当然还会有很多细节。比如这些随机偏移量是在drawcall前就准备好的,并且还会准备一张噪音纹理使得采样更加随机。比如采样到的深度值最好加一点bias(介绍shadow mapping时有介绍bias)又比如,这个严重的漏洞。

直观理解SSAO原理_第3张图片

如图所示,这位大叔上半边的轮廓明显被盖上了一层灰影。

这是为什么呢?原因其实不是出在大叔身上,大叔他本身是不会散发出黑气的.....

问题出在大叔背后的墙壁上,那圈灰影所在的片元(墙壁的)在计算遮蔽因子时,蓝色小点会采样到大叔身上对应的z值,这就出问题了。。解决办法也很简单,把蓝色小点的z和采样到的大叔z值相减,就能得到他们的距离,用这个距离去动态调整最后的遮蔽因子结果即可

你可能感兴趣的:(图形学和shader)