OpenGL 屏幕空间环境光遮蔽(SSAO)详解

发表于2018-03-02
评论0 7.9k浏览
AO:环境光照遮蔽,是一种间接光照的模拟。

它的原理是通过将褶皱、孔洞和非常靠近的墙面变暗的方法近似模拟出间接光照。这些区域很大程度上是被周围的几何体遮蔽的,光线会很难流失,所以这些地方看起来会更暗一些。

屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO)的技术,这一技术使用了屏幕空间场景的深度而不是真实的几何体数据来确定遮蔽量。

原理:对于铺屏四边形(Screen-filled Quad)上的每一个片段,我们都会根据周边深度值计算一个遮蔽因子(Occlusion Factor)。这个遮蔽因子之后会被用来减少或者抵消片段的环境光照分量。遮蔽因子是通过采集片段周围球型核心(Kernel)的多个深度样本,并和当前片段深度值对比而得到的。高于片段深度值样本的个数就是我们想要的遮蔽因子。

思考1:什么样的条件,会被认为是满足遮蔽条件,为什么这是合理的。
采样深度,低于空间实际片段深度。
合理性来源于。
当采样点深度,低于空间实际片段深度的时候,我们就是认为,这个点会被挡住。
我们不需要去考虑实际空间中那些复杂的情况,我们只需要知道,Z-Buffer,认为这个点被挡住了,那么他就是看不见的,就是被遮蔽的。
如果有64个采样点,一半被遮蔽了,那么环境光的采纳率就是50%。

思考2:为什么采用法向半球,而不是采用全球?
如果采用全球,如图:
即使是平坦的表面,也会有一半的遮蔽因子——在平面之下的那些(简单理解为空间探测球)会被遮住,整个画面整体趋势就是灰蒙蒙的了,这虽然简单,但是效果却不佳。

思考3:当初想到这个方法的人,是怎样思考这个问题的。
2.1-想到了在屏幕空间中做,也就是以类似后期的方式去做,不是在真实场景中进行复杂的计算
2.2-想到了利用G-Buffer。
2.3-想到了利用切线空间。
2.4-想到了利用随机方向微调和模糊去解决阶梯感和颗粒感的问题。

这也为我们解决问题提供了一些共性思路:某些复杂的操作,在3D空间做很耗的尝试在屏幕空间做,针对每个表面的计算很复杂的时候,想到在屏幕空间做,当遇到颗粒感或者阶梯感的时候,想到用模糊去解决问题,当然,前提是,模糊只是影响某种分量,而不是针对原模型的片段进行模糊。

延迟渲染所需要的数据:
  • 逐片段位置向量
  • 逐片段的法线向量
  • 逐片段的反射颜色
  • 采样核心
  • 用来旋转采样核心的随机旋转矢量
因为是在屏幕空间做的,也就是说,我们要像处理Defered Render那样,把所需要的数据写入到G-Buffer里面,这也说明了SSAO和Defered Render可以完美兼容。

由于对每个表面法线方向生成采样核心非常困难,也不合实际,我们将在切线空间(TangentSpace)内生成采样核心,法向量将指向正z方向。(这里又用到了切线空间)

思考4:什么时候需要用到切线空间?
当处理空间中每个表面进行计算,感到非常麻烦的时候,统一变换到切线空间去处理。

思考5:空间中的随机采样点,是如何采样,并确定是被遮蔽的。
用采样点的深度值,去和屏幕空间的深度值去比较。
这之前,要把切线空间中的采样点,变换到切线空间。计算采样实际位置之后(sample = fragPos + sample * radius; )在变换到投影空间,这时候才能和存储在G-Buffer里面的深度信息,进行比较。

思考6:模糊效果会影响原来的模型吗?
不会。模糊只是影响了SSAO。模糊并不是针对原模型而言的,只是针对原模型收到光照分量中,环境光部分的遮蔽情况。

尽管SSAO是一个很微小的效果,可能甚至不是很容易注意到,它在很大程度上增加了合适光照场景的真实性,它也绝对是一个在你工具箱中必备的技术。

思考7:
环境光吸收常量从0.3变到0.1会怎样?整体变暗,黑边因为周围环境变暗而显得更细(更难以区分)

思考8:
增加采样点会有什么样的效果?引用区似乎更细腻一些,但是也并不明显(黑色区域更深更细腻)

256

64

思考9:加大模糊采样范围之后,墙上的圆轮并没有消失……那么墙上的圆轮如何才能消失呢?
结论:关掉SSAO并没有解决问题。
那么试试关掉模糊。
结论:关掉Blur颗粒感明显,圆轮还是没有消失,估计是正常光照的锅,不管他了。

计算采样点深度值,计算采样点深度值的平滑插值,以及比较采样点深度和周围像素的深度的比较算法。原教程写的很明白,虽然有点小复杂这里也不细说了

SSAO的整体流程示意图:
  1. 渲染正常几何体,到G-Buffer
  2. 利用G-Buffer中的数据,通过TBN矩阵,将采样点从切线空间,变换到视图空间,并在这个空间比较并计算SSAO的值,并写入AmbientOcculction
  3. 对AmbielntOcculction Texture进行模糊处理,去掉噪声
  4. 利用AmbielntOcculction Texture 获得正确的环境光照遮蔽效果。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引