Real-Time Global Illumination(screen space)
Screen Space Ambient Occlusion:屏幕空间环境光遮蔽,在屏幕空间中的全局光照的一种近似。
假设SSAO的着色点的光照是来源于次级光源或多次弹射,且都是diffuse的。但它和布林冯着色模型并不一样。
在这两点上不一样,考虑visibility,如果不考虑visibility,接收到的所有光就会一样,看起来就会像是一个平面。考虑visibility后,某些着色点所接收到的光就会不一样。这里也假设材质都是diffuse的。
从渲染方程开始
间接光照是常数,着色点材质是diffu。所有BRDF是常数,把这两项拿到积分外,这时就剩下visibility的加权求和
计算visibility的加权求和,分在3D空间和屏幕空间下。
在3D空间下,要考虑在一定范围内的环境光照遮挡情况,如果过小,就会忽略掉来自远方向的环境光照,如果过大,就会没有实际意义,因为一般的环境光遮挡都是来自于近处的物体遮挡。
在屏幕空间下,SSAO用了大胆的假设,以着色点为圆心创建一个球,然后在这个球内随机取点,如何判断取得点能够被着色点看到,通过camera视角下的z-buffer可以知道最浅深度,如果取到的点大于最浅深度,就会看不见,反之就能看见。当然这里会有一点点的小问题,在下面中间的图中,有一个点,可以被着色点看到,但它的深度大于z-buffer的最浅深度,就会被当作看不见。不过由于是工业界用法,所以忽略这个错误了。
在以前的年代,shadow map记录的内容中没有法向量,所以要用一个球方式来判断visibility的情况,但现在已经有了法向量,也就是只需要用半球就可以了。
在没有法向量的情况下,以图中为列,如果红色点没有超过一办,说明没有被遮挡,在超过一半后开始计算visibility.
下图说明SSAO的一个错误,在右图的画圈中,石凳对地面的环境光遮蔽提供了贡献,是因为在屏幕空间下,被石凳挡住的部分会是红点。
SSAO的球中采样点,不能太多也不能太少,得到一个noise的AO
然后进行dinoise,获得一个模糊的效果,这样AO就可以用了
Screen Space Directional Occlusion(SSDO)
SSDO和path trace很相似,SSDO所接收到环境光是来自于附近的次级光源对其的贡献
SSAO和SSDO正好是完全相反的,SSAO的着色点光源贡献是来自于环境光,如果附近有物体,就会遮挡环境光对其的照射。SSDO的着色点光源贡献是来自于附近的物体所弹射的光,这点就和path trace很像,而较远处的环境光对其就没有贡献。
着色都需要从渲染方程出发,SSDO只需要考虑被遮挡的部分,也就是V=0。
SSDO也是从camera的视角出发,以着色点为球心,法线指向上面建立一个半球,也是在半球内随机取点,然后通过和Z-buffer比较深度,如果深度大于Z-buffer,说明对着色点有贡献,如果小于Z-buffer说明没有贡献。这时可以计算环境光对其贡献,但这里忽略这点。
SSDO也存在一些问题,在下图最右边的部分中,A点因为因为深度大于Z1,所以被判定为对着色点有贡献,但实际情况是没有贡献。而B点被判定成没有贡献,因为它的深度小于Z-buffer对应的最小深度,实际情况是p点连向B点后会碰到物体,这个物体会对p点做出贡献。
SSDO的一些问题:它适用于小范围的环境光,它的可见性是根据camera来计算的,会不够准确。它还有一个比较大的问题,以下面的黄色墙壁为例,当camera能够看到一个较为完整的墙面时,地面会接收到墙面的黄色弹射光,而当camera看到的是墙的侧面时,地面是无法接收到墙面的反射光的,因为必须要从camera视角下计算,而实际情况是地面必须会接收到墙面的反射光。
Screen Space Reflection (SSR):也是实时的全局光照,只不过不是在3D空间下,而是在屏幕空间下。
可以用SSR在地面上做一个镜面反射光
实现SSR的思路:从camera角度看向着色点,然后光线在着色点反弹到物体表面。这里要判断光线和物体表面的相交。在判断的时候,需要隔一段距离(步长)就要判断光线是否已经和物体相交了,而这个步长太长的话会导致已经相交了才被发现,太短的话会增加计算量。所以人们引用了动态步长。这里的步长是一个固定值。
在动态步长中,因为步长太小,往前几次都不会和物体相交,所以想要直接一步就跨过这个距离。
这里使用一个类型MIPMap的结构,它的上一层的一个像素不再是下一层相对于四个像素的平均值,而是和场景最近距离的最小值。