8.0 Lession 8 环境光遮蔽

[TOC]

参考资料

AO (ambient occlusion)

说一下我的理解,TinyRenderer之前对光照的计算基于Phong光照模型,Phong光照模型是局部光照模型,环境光使用的都是常量,模拟的效果并不是特别逼真,比如管道内部比外部更暗,如果环境光是常数就看不出来这种感觉。我理解实时光线追踪技术实现成本比较高,AO的出现是采用相对折中的方法来达到效果的平衡。AO实现的方式很多,这里只记录SSAO。

SSAO

SSAO的实现可分为三个步骤: 计算AO, 模糊/滤波, 与Color Buffer混合.

计算AO

计算AO的核心问题在于如何取采样点并判断这些采样点是否被遮蔽.

  • 第一个问题:如何去采样点?

    • 法向半球体(Normal-oriented Hemisphere)周围采样
  • 第二个问题:如何判断下图中的采样点遮蔽情况呢

    • 将采样点全部投影到View Plane上, 相当于获取采样点的UV坐标, 并同时获取Depth Buffer中该UV坐标处的深度值. 随后比较采样点的深度和场景中该点的深度. 如果采样点的深度更大, 说明其被场景遮蔽. 最终将所有采样点的AO贡献求和, 即是该点的AO值

模糊/滤波

一种方式是采用高斯模糊

Color Buffer

一般加入Gamma Correction使得阴影更有层次感, 即最终结果为:

tex2D ( _MainTex, i.uv ) * pow ( ( 1 - occlusion ), 2.2 );

TinyRenderer

TinyRenderer的Lession8,首先介绍了AO的概念和半球采样。

demo中第一次先计算1000次半球采样的深度平均值,参考Lesson7的shadow的计算,将深度值以纹理的相同位置保存在了灰阶图片中,能看到的点保存为白色255,课程中的采样点的选取以随意eye的位置,在上半球上随机点选取。最终将每次循环得到的点的颜色进行加权平均。

下面是1000次采样的AO图。

这种全局采样的方法比较耗时,但是像前面所描述的,可以预先处理得到AO图像,下次渲染再使用以降低成本。

lession8并没有将AO的图应用在最终的渲染结果。

lesson7中没有加shadow计算,是下图的效果

根据tex2D ( _MainTex, i.uv ) * pow ( ( 1 - occlusion ), 2.2 );将AO图应用在渲染图得到下面的效果。

可以看到明暗效果确实比之前要好一些,但是明暗最终还是需要再调整(有时间再调整)

TinyRenderer 的 SSAO

//TODO