demo
SSAO
- 环境光照(Ambient Lighting):光的散射,我们通过一个固定的常量作为环境光的模拟,
- 但是这种固定的环境光并不能很好模拟散射,因为环境光不是一成不变的,
- 环境光遮蔽:让(褶皱、孔洞)等变暗的方法近似模拟出间接光照,但是这一技术会带来很大的性能开销,因为它还需要考虑周围的几何体。
- 屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO):这一技术使用了屏幕空间场景的深度而不是真实的几何体数据来确定遮蔽量。
- 原理:对于铺屏四边形(Screen-filled Quad)上的每一个片段,我们都会根据周边深度值计算一个遮蔽因子(Occlusion Factor)。这个遮蔽因子之后会被用来减少或者抵消片段的环境光照分量。
- 遮蔽因子是通过采集片段周围球型核心(Kernel)(球的立体空间内)的多个深度样本,并和当前片段深度值对比而得到的。高于片段深度值样本的个数就是我们想要的遮蔽因子。几何体内样本个数越多,遮蔽因子就越多,片段获得的环境光照也就越少。
- 优化性能:如果样本数量太低,渲染的精度会急剧减少,我们会得到一种叫做波纹(Banding)的效果;如果它太高了,反而会影响性能。我们可以通过引入随机性到采样核心(Sample Kernel)的采样中从而减少样本的数目。
- 但是:使用球体采样,导致平整的墙面也会显得灰蒙蒙的,因为球心的一半都在墙的底部,片段的深度会高于当前的深度值,从而遮蔽因子越多,我们通过在法向半球体(Normal-oriented Hemisphere)周围采样,从而不会考虑墙面底部
计算:
- G缓冲?
- 将法向半球对准片段的观察空间表面法线。所有法线都是从相机到片段的方向向量,
- 我们对铺屏2D四边形上每一个片段计算遮蔽因子,但是我们没有场景的几何信息,可以利用G缓冲,让它包含片段的线性深度,通过利用gl_FragCoord.z以及非线性深度值转线性深度值的公式,
- 法向半球采样器 & 切线空间:
- 法向半球采样器 :在切线空间内(也就是物体的局部空间下)生成采样核心,通过指定具体的采样点数量,在切线空间中以-1.0到1.0为范围变换x和y方向,并以0.0和1.0为范围变换样本的z方向(如果以-1.0到1.0为范围,取样核心就变成球型了)
- 优化:将核心样本靠近原点分布。用一个加速插值函数实现它:近似于x^2,
- 随机采样器:
- 噪声:随机旋转向量
- SSAO GLSL:
- 利用G缓冲的数据
- 在2D的铺屏四边形上运行,对于每一个生成的片段计算遮蔽值,由于我们需要存储SSAO阶段的结果,我们还需要在创建一个帧缓冲对象:
- 环境遮蔽模糊:
- 我们又创建了一个帧缓冲对象来储存模糊结果
- 光照 GLSL:
- 利用SSAO的遮蔽数据,只需要改变原来的环境光照分量*遮蔽因子