屏幕空间环境光遮蔽(SSAO)算法
影响SSAO系数的因素
- 场景深度
- 表面点法向量
- 法向量半球的半径
- 采样点个数
- 采样点分布
- 场景深度不连续
- 由于场景深度不连续以及采样点是预设的,并不能完全展现真实积分后的结果
- 还可能带来一些错误的结果
- 采样点的离散分布还会带来噪点的问题,所以一般会和降噪、模糊等算法配合使用
Shader实现
原版算法实现
- 根据uv随机采样得到颜色向量
- 将随机得到的颜色向量通过乘2减1的变换转到[-1, 1]区间,这是用来做整个球体内的随机法线
- 将变换后的随机向量与表面法向量点乘,小于0代表夹角大于90°了,已经不是法线半球内的向量了,可以将随机法线向量乘以-1,也就变换到法线半球内了,不会浪费本次的随机
- 之后将随机向量乘以法向量半球的半径,确保在法向量半球内随机一个点,并投影到近平面上
- 通过getPosition函数获得表面点屏幕对应uv,加上随机点投影到屏幕上的位移,来获取世界坐标系下随机采样点在世界深度外壳上的点
- 这里由于是GPU Sample,是一遍Pass的程序,利用了已有的有向距离场信息,重新计算Ray marching找到采样点在世界深度外壳上的点;而如果是显式模型渲染情况下,一般是通过两边Pass,第一遍拿到场景深度信息或场景深度与场景法线信息,第二遍Pass根据场景深度信息或场景深度与场景法线信息重构三维空间来找到这个随机采样点在世界深度外壳上的点
- 然后根据这个点与表面点,也就是半球球心点来构建向量,通过这个向量与法向量点乘夹角的cos值判断遮蔽情况,夹角越大,对应的遮蔽影响也越大
- 后面除以两点间距离+1 /(length(diff) + 1.0) ,是为了做遮蔽值影响的衰减,距离越大,影响越小
- 另外,采样点个数也是预定义的,采样点越少,AO的噪点就会越明显,可以通过模糊算法来处理