HPP_Graphics_4.2 SSAO
a). AO(Ambient Occlusion)
环境光遮蔽,全称Ambient Occlusion,是计算机图形学中的一种着色和渲染技术,模拟光线达到物体的能力的粗略的全局方法,描述光线到达物体表面的能力。
b). SSAO(Screen Space Ambient Occlusion)
屏幕空间环境光遮蔽,全称Screen Space Ambient Occlusion,一种用于计算机图形中实时实现近似环境光遮蔽效果的渲染技术。通过获取像素的深度缓冲、法线缓冲以及像素坐标来计算实现,来近似的表现物体在间接光下产生的阴影。
b.1). SSAO原理
获取深度、法线(View Space)缓冲;
Normal Buffer:
重构像素相机空间中的坐标;
通过深度缓冲的depth值重构(近似)该视角下的三维场景;
- 为什么是近似:Depth Buffer中深度值为0~1,并不能反应无穷远(天空等)。常用的办法是把1映射到View Space的远平面。
法向半球随机采样,计算掩蔽因子,进而得到AO强度(For循环);
- 每一次for循环都会在法线半球中获取一个随机向量,根据这个向量我们会求出它对应的深度值,然后跟深度缓冲中对应采样像素位置的深度值做比较,如果大于(灰色点),则认为有遮蔽,算进加权中,最后我们合成AO,然后再加上一些后期处理优化效果。
b.2). Unity实现部分
SSAO的shader中共有三个Pass:
- 计算生成AO;
- 模糊 / 滤波
- AO与Color buffer混合;
b.2.1). 计算AO
在基于法线方向,建立法线空间中法向半球的采样块。
在采样块中循环生成采样点,判断是否被遮蔽
因为实时渲染的性能问题,所以采样点数量不会很多,导致出现“油漆”般的画面
引入噪声, 将每个采样点以原点法线方向为旋转轴旋转随机的角度。这样的新采样点会变得极其不规则, 更加离散化。将低频的条纹转化成高频的噪声;
计算相机到像素点的坐标(Unity Shader中的ComputeScreenPos函数)对应的远平面的向量(屏幕空间转换到裁剪空间后乘以远平面距离,再转换到观察空间);
获得着色点的01线性深度值、观察空间下的法线向量;
然后在法向半球采样块中随机随机采样一个向量,得到法向半球向量。并由此构建经过旋转的法线空间的正交基。
将此前生成的随机向量转换到法线空间中。
循环操作,将每一个向量转换为采样点,坐标基于切线空间,再计算随机法向半球后的向量,然后进行空间转换,切线空间到裁剪空间到屏幕空间。(裁剪空间到屏幕空间进行01映射)
获得采样点的法线深度信息,计算遮蔽,最后得到AO图通过rscreenPos来采样_CameraDepthNormalsTexture,转化成屏幕空间对应的深度值,然后对比linear01Depth(着色点深度,更准确的情况下应该使用viewRandomPos对应的01线性深度),只要大于linear01Depth,则在加权计算AO
AO核心代码
延迟渲染+ssao
因为在前向渲染的ssao实现过程中,需要获取到相机的法线深度图进行采样得到相应的信息,进行后续的操作。而因为延迟渲染正好需要先生成一个GBuffer,即已包含了ssao执行所需要的法线深度等信息。所以在shader代码编写中有所不同
在c#脚本中需要加入渲染路径的判断
b.2.2). 基于法线的双边滤波(Bilateral Filter)
https://blog.csdn.net/puppet_master/article/details/83066572
Homework
场景1
这场景好像不太明显,只有在大图里看的清楚,