4.2 SSAO算法 屏幕空间环境光遮蔽

一、SSAO介绍

AO4.2 SSAO算法 屏幕空间环境光遮蔽_第1张图片

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

4.2 SSAO算法 屏幕空间环境光遮蔽_第2张图片

SSAO

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

4.2 SSAO算法 屏幕空间环境光遮蔽_第3张图片

SSAO历史

AO这项技术最早是在Siggraph 2002年会上由ILM(工业光魔)的技术主管Hayden Landis所展示,当时就被叫做Ambient Occlusion。

2007年,Crytek公司发布了一款叫做屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO)的技术,并用在了他们的看家作孤岛危机上。


二、SSAO原理

  • 计算深度、法线缓冲
  • 深度->像素坐标
  • 法线->法向半球随机向量
  • 计算像素随机后的坐标(多次采样)
  • 获取随机后深度并比较
  • 判断加权AO
  • 后期(模糊等)

4.2 SSAO算法 屏幕空间环境光遮蔽_第4张图片

样本缓冲

  • 深度缓冲
    • 深度缓冲中的depth值用于当前视点下场景的每一个像素距离相机距离的一个粗略表达,用于重构像素相机空间中的坐标(Z),来劲死重构该视点下的三维场景。
    • 4.2 SSAO算法 屏幕空间环境光遮蔽_第5张图片

  • 法线缓冲
    • 相机空间中的法线信息,用于重构每个像素的“法线-切线-副切线”构成的坐标轴,用于法线半球中的采样随机向量(随机向量用于判断、描述该像素的AO强度)。
    • 4.2 SSAO算法 屏幕空间环境光遮蔽_第6张图片

法向半球

4.2 SSAO算法 屏幕空间环境光遮蔽_第7张图片

4.2 SSAO算法 屏幕空间环境光遮蔽_第8张图片

  • 黑色表示我们需要计算的样本
  • 蓝色向量表示样本的法向量
  • 白色灰色为采样点(很明显,采样点的多少影响最后的渲染效果),其中灰色表示被遮挡采样点(深度大于周围),据此判断最终AO的强度。
  • 右图表示法向球形采样(后背抛弃),原因是该方式采样导致凭证的墙面也会显得灰蒙蒙的,因为和心中一般的样本都会在墙这个几何体上。


三、SSAO算法实现

Buffer

  • 获取深度&法线缓冲数据
  • C#部分
  • 4.2 SSAO算法 屏幕空间环境光遮蔽_第9张图片

  • Shader部分
  • 4.2 SSAO算法 屏幕空间环境光遮蔽_第10张图片

  • UnityCG.cginc
  • 4.2 SSAO算法 屏幕空间环境光遮蔽_第11张图片

如果是延迟渲染这一步可以省略,G-Buffer中可以直接拿到

中间相机空间坐标

  • 重建方法
    • 参考链接:Unity从深度缓冲重建世界空间位置 - 知乎
    • 本例实现使用其中的“NDC空间中重构”方法得到样本在相机空间中的向量,乘以深度值得到样本的坐标。
  • 从NDC空间重建
    • 1.计算样本屏幕坐标(利用Unity内置的函数)
    • 2.转化至NDC空间中
    • 3.计算相机空间,从中到远屏幕的方向(内置变量_ProjectionParams.z存放相机远平面值far)
    • 4.矩阵变换至相机空间中的样本相对相机的方向
    • 4.2 SSAO算法 屏幕空间环境光遮蔽_第12张图片

    • 5.重构相机空间的样本坐标(在像素着色器中)
    • 4.2 SSAO算法 屏幕空间环境光遮蔽_第13张图片

    • 在相机空间中通过样本的相对相机方向以及深度,来拟合重构坐标

构建法向量正交基

  • 设置法向量
  • 生成随机向量(用于构建的正交基随机,而非所有样本计算的到的正交基一致),先归一化
  • 求出切向量,再利用函数cross叉积求副切线向量
  • 4.2 SSAO算法 屏幕空间环境光遮蔽_第14张图片

  • 4.2 SSAO算法 屏幕空间环境光遮蔽_第15张图片

AO采样核心

  • 传入给定的随机采样向量,并通过法向量正交基转化至法线半球中的向量。

  • 获取随机坐标点。
  • 转换至屏幕空间坐标

  • 计算随机向量转化至屏幕空间后对应的深度值,并判断累加AO

    4.2 SSAO算法 屏幕空间环境光遮蔽_第16张图片


四、SSAO效果改进

随机正交基(增加随机性)

  • 为了不使求得的法向半球的正交基一致,我们引入随机向量,已求得不用想象的切向量。
  • 利用uv采样一张Noise贴图(如下图4x4像素的Noise贴图,可选择其他尺寸),或者随机向量。
  • 4.2 SSAO算法 屏幕空间环境光遮蔽_第17张图片

  • 并在C#中传入噪声贴图。

AO累加平滑优化

范围判定(模型边界)

  • 样本采样,可能会采集到的深度差非常大的随机点,会导致边界出现AO,如下图
  • 4.2 SSAO算法 屏幕空间环境光遮蔽_第18张图片

    4.2 SSAO算法 屏幕空间环境光遮蔽_第19张图片

  • 加入样本深度和随机点的深度值判定(效果如下图)
  • 4.2 SSAO算法 屏幕空间环境光遮蔽_第20张图片

自身判定

如果随机点深度值和自身一样或者非常接近(可能会导致虽然在同一平面,也会出现AO),如下图

4.2 SSAO算法 屏幕空间环境光遮蔽_第21张图片

判断深度值的大小时,增加一个变量,来改善问题

4.2 SSAO算法 屏幕空间环境光遮蔽_第22张图片

AO权重

AO深度判断,非0即1,比较生硬,为其增加一权重,如下图

4.2 SSAO算法 屏幕空间环境光遮蔽_第23张图片

本例中的权重为:发现半球中随机采样后的点x、y(切线平面)距离样本的距离为参考

4.2 SSAO算法 屏幕空间环境光遮蔽_第24张图片

4.2 SSAO算法 屏幕空间环境光遮蔽_第25张图片

模糊

采用基于法线的双边滤波原理(Bilateral Filtering)

4.2 SSAO算法 屏幕空间环境光遮蔽_第26张图片

4.2 SSAO算法 屏幕空间环境光遮蔽_第27张图片


五、对比模型烘焙AO

烘焙方式

  • 三维建模软件烘焙AO方式
    • 通过三维建模软件(如3DMax),设定好渲染参数,对模型(单一选择模型实体),烘焙AO到纹理。
  • 游戏引擎烘焙AO方式(Unity3D Lighting)
    • 通过Unity的Lighting功能(主菜单/Window/Rendering/Lighting Settings)进行整体场景的烘焙,AO信息包含于此。

建模软件烘焙优缺点

  • 优点
    1. 单一物体可控性强(通过单一物体的材质球上的AO纹理贴图),可以控制单一物体的AO的强弱;
    2. 弥补场景烘焙的细节,整体场景的烘焙(包含AO信息),并不能完全包含单一物体细节上的AO,而通 过三维建模软件烘焙到纹理的方式,增加物体的AO细节;
    3. 不影响其(Unity场景中)静态或者动态;
  • 缺点
    1. 操作较其他方式繁琐,需要对模型进行UV处理,再进行烘焙到纹理;
    2. 不利于整体场景的整合(如3DMax烘焙到纹理,只能选择单一物体,针对整体场景的处理工作量巨大);
    3. 增加AO纹理贴图,不利于资源优化(后期可通过其他纹理通道利用整合资源);
    4. 只有物体本身具有AO信息,获取物体之间的AO信息工作量巨大(不是不可能)。

Unity烘焙优缺点

  • 优点
    1. 操作简易,整体场景的烘焙,包含AO的选择;
    2. 不受物体本身的UW影响,Unity通过Generate Lightmap UVs生成模型第二个纹理坐标数据;
    3. 可生成场景中物体与物体之间的AO信息;
  • 缺点
    1. 缺少单一物体的细节(可调整参数提高烘焙细节,但换之将增加烘焙纹理数量和尺寸,以及烘焙时间);
    2. 受物体是否静态影响,动态物体无法进行烘焙,获得AO信息。

SSAO优缺点

  • 优点
    1. 不依赖场景的复杂度,其效果质量依赖于最终图片像素大小;
    2. 实时计算,可用于动态场景;
    3. 可控性强,灵活性强,操作简单;
  • 缺点
    1. 性能消耗较之上述2种方式更多,计算非常昂贵;
    2. AO质量上要比较离线式烘焙(上述2种)不佳(理论上)。

六、SSAO性能消耗

AO核心采样消耗说明

AO法向半球的随机采样

4.2 SSAO算法 屏幕空间环境光遮蔽_第28张图片

双边滤波的多重采样

4.2 SSAO算法 屏幕空间环境光遮蔽_第29张图片

4.2 SSAO算法 屏幕空间环境光遮蔽_第30张图片

本例SSAO算法中,主要核心为计算AO随机法向半球的采样点,并加以半段计算AO权值。

  1. 利用For结构代码进行半球堆积向量的采样,If、For等对于GPU计算性能上不友好

    4.2 SSAO算法 屏幕空间环境光遮蔽_第31张图片

  2. 采样数的数量(上图的_SmpleKernelCount,针对For循环的次数),过低的采样数得不到好的结果;以64为例,1334*750的分辨率,每个像素计算循环64次,合计1334*750*64次AO核心计算。
  3. 循环体重采样,同样以64为例,每个像素计算需要采样64次来求得屏幕深度值法线值。

    4.2 SSAO算法 屏幕空间环境光遮蔽_第32张图片

滤波采样消耗说明

本例采用的是双边滤波(Bilateral Filter),为保证不被模糊,采样基于法线的双边滤波。

  1. C#后期脚本中,Blit两次(横向和纵向),合计调用两次滤波渲染Pass;

    4.2 SSAO算法 屏幕空间环境光遮蔽_第33张图片

  2. 单一滤波渲染Pass中,多重采样,包括7次主纹理的采样和7次屏幕像素的法线信息的采用,屏幕中每个像素合计14次纹理采样。

你可能感兴趣的:(游戏开发,算法,数码相机)