HPP_Graphics_4.2 SSAO

a). AO(Ambient Occlusion)

环境光遮蔽,全称Ambient Occlusion,是计算机图形学中的一种着色和渲染技术,模拟光线达到物体的能力的粗略的全局方法,描述光线到达物体表面的能力。

AO00

b). SSAO(Screen Space Ambient Occlusion)

屏幕空间环境光遮蔽,全称Screen Space Ambient Occlusion,一种用于计算机图形中实时实现近似环境光遮蔽效果的渲染技术。通过获取像素的深度缓冲法线缓冲以及像素坐标来计算实现,来近似的表现物体在间接光下产生的阴影。

b.1). SSAO原理

SSAO原理

  1. 获取深度、法线(View Space)缓冲;

    • Normal Buffer:

      NormalBuffer

  2. 重构像素相机空间中的坐标;

    • 通过深度缓冲的depth值重构(近似)该视角下的三维场景;

      DepthBuffer

      • 为什么是近似:Depth Buffer中深度值为0~1,并不能反应无穷远(天空等)。常用的办法是把1映射到View Space的远平面。
  3. 法向半球随机采样,计算掩蔽因子,进而得到AO强度(For循环);

    法向半球

    • 每一次for循环都会在法线半球中获取一个随机向量,根据这个向量我们会求出它对应的深度值,然后跟深度缓冲中对应采样像素位置的深度值做比较,如果大于(灰色点),则认为有遮蔽,算进加权中,最后我们合成AO,然后再加上一些后期处理优化效果。

b.2). Unity实现部分

AO_Flow

SSAO的shader中共有三个Pass:

  1. 计算生成AO;
  2. 模糊 / 滤波
  3. AO与Color buffer混合;

b.2.1). 计算AO

在基于法线方向,建立法线空间中法向半球的采样块。

在采样块中循环生成采样点,判断是否被遮蔽

因为实时渲染的性能问题,所以采样点数量不会很多,导致出现“油漆”般的画面

引入噪声, 将每个采样点以原点法线方向为旋转轴旋转随机的角度。这样的新采样点会变得极其不规则, 更加离散化。将低频的条纹转化成高频的噪声;

  1. 计算相机到像素点的坐标(Unity Shader中的ComputeScreenPos函数)对应的远平面的向量(屏幕空间转换到裁剪空间后乘以远平面距离,再转换到观察空间);

    vertAO

  1. 获得着色点的01线性深度值、观察空间下的法线向量;

    GetDepthAndNormal

  2. 然后在法向半球采样块中随机随机采样一个向量,得到法向半球向量。并由此构建经过旋转的法线空间的正交基。

    Noise01a

    TBN

  3. 将此前生成的随机向量转换到法线空间中。

    Noise02a

    循环操作,将每一个向量转换为采样点,坐标基于切线空间,再计算随机法向半球后的向量,然后进行空间转换,切线空间到裁剪空间到屏幕空间。(裁剪空间到屏幕空间进行01映射)

    scrRandomVec

    获得采样点的法线深度信息,计算遮蔽,最后得到AO图通过rscreenPos来采样_CameraDepthNormalsTexture,转化成屏幕空间对应的深度值,然后对比linear01Depth(着色点深度,更准确的情况下应该使用viewRandomPos对应的01线性深度),只要大于linear01Depth,则在加权计算AO

    For02a

AO核心代码

fragAO

延迟渲染+ssao

因为在前向渲染的ssao实现过程中,需要获取到相机的法线深度图进行采样得到相应的信息,进行后续的操作。而因为延迟渲染正好需要先生成一个GBuffer,即已包含了ssao执行所需要的法线深度等信息。所以在shader代码编写中有所不同

Defer01

在c#脚本中需要加入渲染路径的判断

Defer02

b.2.2). 基于法线的双边滤波(Bilateral Filter)

https://blog.csdn.net/puppet_master/article/details/83066572

Blur

Homework

场景1

HomeworkAO

Homework01
Homework02

这场景好像不太明显,只有在大图里看的清楚,

场景2

HomeworkAO_b

Homework01b
Homework02b

Homework02b

Homework01b