SSAO的思考

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

SSAO的整体流程:

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

思考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会怎样?整体变暗,黑边因为周围环境变暗而显得更细(更难以区分)。

来源:https://gameinstitute.qq.com/community/detail/122731

猜你喜欢

转载自blog.csdn.net/Gentlemanman/article/details/88934222