IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> TA入门笔记(二十二) -> 正文阅读

[数据结构与算法]TA入门笔记(二十二)

参考
may佬《技术美术百人计划》
游戏后期特效第四发 – 屏幕空间环境光遮蔽(SSAO)

图形4.2 SSAO算法

SSAO介绍

AO(环境光遮蔽)

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

AO的计算公式如下:

A O ( p , n p ) = 1 π ∫ Ω V ( p , ω ) m a x ( n p ? ω , 0 ) d ω AO(p,n_p)=\frac{1}{\pi}\int_\Omega V(p,\omega)max(n_p*\omega,0) d\omega AO(p,np?)=π1?Ω?V(p,ω)max(np??ω,0)dω

n p n_p np?代表点 p p p的法线, ω \omega ω代表点 p p p切平面正方向的任意单位向量, V ( p , ω ) V(p,\omega) V(p,ω)是可见函数, 如果点 p p p ω \omega ω方向被遮挡则为1, 否则为0

SSAO(屏幕空间环境光遮蔽)

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

历史

  • AO这项技术最早是在Siggraph 2002年会上由ILM(工业光魔)的技术主管Hayden Landis所展示,当时就被叫做Ambient Occlusion
  • 2007年,Crytek公司发布了一款叫做屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO)的技术,并用在了他们的看家作孤岛危机

SSAO原理

流程

  • 深度、法线缓冲
  • 深度 → \rightarrow 像素坐标
    • 通过深度信息计算出场景中每个像素在三维空间中的坐标,用于判断和其他像素之间的关系
  • 法线 → \rightarrow 法向半球随机向量
  • 计算像素随机后的坐标(多次采样)
  • 获取随机后深度并比较
  • 判断加权AO
  • 后期(模糊等)
    在这里插入图片描述

样本缓冲

深度缓冲:深度缓冲中的depth值用于当前视点下的场景每一个像素与相机距离的粗略表达,用于重构相机空间中的坐标(Z)来近似重构该视点下的三维场景
请添加图片描述
法线缓冲:相机空间中的法线信息,用于重构每个像素的法线-切线-副切线构成的坐标轴(切线空间),用于计算法线半球中的采样随机向量(随机向量用于判断和描述该像素的AO强度)
请添加图片描述

法向半球

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

为解决第一个问题,使用法向半球——一种指向法线方向的半球形采样块,并在采样快中生成采样点。**距离原点越远的点AO贡献越小
在这里插入图片描述
然后解决第二个问题:判断采样点的遮蔽情况

在这里插入图片描述
(涂黑的点在几何体内部,判定为被遮蔽)

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

公式如下:
A O n ( p ) = 1 n C ( p , s i ) C ( p , s i ) = V ( p , s i ) c o s ( s i ? p , n p ) D ( s i ? p ) AO_n(p)=\frac{1}{n}C(p,s_i)\\ C(p,s_i)=V(p,s_i)cos(s_i-p,n_p)D(s_i-p) AOn?(p)=n1?C(p,si?)C(p,si?)=V(p,si?)cos(si??p,np?)D(si??p)

函数 V V V是可见函数, 如果点 p p p ω \omega ω方向被遮挡则为1, 否则为0;
函数 D D D是一个[0,1]之间的单调递减函数,距离原点越近的采样点对AO的贡献越大,一般使用指数函数

最初的SSAO使用的采样核心是完整的球体,由于核心中一半的样本都在几何体内部,这会导致平整的墙面变得灰蒙蒙的。使用半球进行采样可以消除这种影响,产生更真实的结果。
请添加图片描述请添加图片描述

SSAO算法实现

Buffer

获取深度&法线缓冲数据

C#:获取相机组件,调整相机的深度纹理生成模式(Depth、DepthNormals、MotionVectors)
请添加图片描述
Shader:

在shader中声明变量来获取当前屏幕的深度法线图
请添加图片描述
对其进行采样来获取深度值和法线值,采样uv为屏幕空间的uv
请添加图片描述
最后一行解码函数在UnityCG.cginc中的解释如下
请添加图片描述

  • 场景中的项目为透视模式
  • 相机渲染路径为Forward,如果设置为Deffered渲染路径,则对应的G-Buffer中已经生成了深度和法线信息,在shader中可作为全局变量访问
  • 使用OnRenderImage()来处理后期实现SSAO

重建相机空间坐标

参考本文,使用其中的“从NDC空间中重建”方法得到样本在相机空间中的坐标,乘以深度值后得到样本坐标

1. 计算样本屏幕坐标
请添加图片描述
屏幕坐标输出为颜色之后如下图所示,原点(0,0,1)为蓝色,右上角(1,1,1)为白色
请添加图片描述

2. 转换至NDC空间中
在这里插入图片描述
请添加图片描述
3. 计算相机空间中至远平面方向

将屏幕像素对应在摄像机远平面的点转换到裁剪空间。因为在NDC空间中远平面上的点的z分量为1,所以可以直接乘摄像机的far值来将其转换到裁剪空间(反向透视除法)
请添加图片描述
4. 通过逆投影矩阵变换至相机空间中的样本相对相机的方向
请添加图片描述
已知在观察空间中摄像机的位置一定为(0,0,0),所以从摄像机指向远平面上的点的向量就是其在观察空间中的位置

5. 重建相机空间中的样本坐标

在相机空间中通过样本相对相机的方向和深度来拟合重构坐标,获得了基于相机的3D场景
请添加图片描述

构筑法向量正交基

在这里插入图片描述

  • 随机向量将通过采样一张随机贴图来实现,用于改变向量的方向
  • 通过 a ? = ( N ? ? R ? ) ? N ? , T ? = R ? ? a ? \vec a=(\vec N ·\vec R)·\vec N,\vec T=\vec R-\vec a a =(N ?R )?N ,T =R ?a 来求得切线

AO采样核心

1. 传入给定的随机采样向量,并通过法向量正交基转化至法线半球中的向量
请添加图片描述

  • _SampleKernelArray参数在C#脚本中计算了随机值,可以在之前一次随机的基础上再进行一次随机

2. 随机获取坐标点
请添加图片描述

  • _SampleKernelRadius为法向半球的半径
  • 视觉空间坐标可以看作向量,通过向量加法求得随机采样点
    在这里插入图片描述

3. 转换至屏幕空间
请添加图片描述
4. 计算随机向量转化至屏幕空间之后对应的深度值,并判断累加AO
请添加图片描述

  • 比较随机点和该点所在的屏幕像素的深度值,若随机点更靠近相机则判断对AO有贡献,更远的话就没有贡献

在这里插入图片描述

SSAO效果改进

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

通过引入随机变量或者采样噪音贴图来使得法向半球的正交基不一致

此处使用了一张4×4的Noise贴图
请添加图片描述
请添加图片描述
在C#中传入噪声贴图
请添加图片描述

AO累加平滑优化

范围判定

样本采样时可能会采集到深度差非常大的随机点,导致边界出现AO
在这里插入图片描述

  • 天空的深度值为1,管道边缘产生的随机点会被判断为对其产生了遮蔽效果

加入样本深度和随机点的深度值的范围判定
请添加图片描述
效果如下
请添加图片描述

自身判定

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

  • 深度值映射到[0,1]之后,同一平面上的点可能会因为误差而产生AO

判断深度值大小时增加一个变量来改善这个问题
请添加图片描述
效果如下
请添加图片描述

AO权重

AO的深度判断非0即1比较生硬
请添加图片描述
为其增加权重,本例的权重以采样点的xy到样本的距离为参考
请添加图片描述
请添加图片描述

请添加图片描述

模糊

采用基于法线的双边滤波
在这里插入图片描述

对比模型烘焙AO

三维建模软件烘焙AO方式

通过三维软件(如3DMax),设定好渲染参数,对单一模型,烘焙AO到纹理

优点:

  • 单一物体可控性强(通过单一物体的材质球上的AO纹理贴图),可以控制单一物体的AO强弱
  • 弥补场景烘焙的细节。整体场景的烘焙(包含AO信息),并不能完全包含单一物体细节上的AO,而通过三维建模软件烘焙到纹理的方式,可以增加物体的AO细节
  • 不影响其(Unity场景中)静态或动态。Unity中只能烘焙静态场景

缺点:

  • 操作繁琐,需要对模型进行UW处理再烘焙到纹理
  • 不利于整体场景的整合(如3DMax烘焙到纹理,只能选择单一物体,针对整体场景的工作量巨大)
  • 增加AO纹理贴图,不利于资源优化(可通过写个shader把贴图整合到其他的纹理通道中)
  • 只有物体本身具有AO信息,获取物体之间的AO信息的工作量巨大

游戏引擎烘焙AO方式

通过Unity的Lighting功能(主菜单/Window/Rendering/Lighting Settings)进行整体场景的烘焙,包括了GI(global illumination,全局光照)、天空盒、AO等信息

优点:

  • 操作简单
  • 不受物体本身UW影响,Unity通过Generate Lightmap UVs生成模型第二个纹理坐标数据
  • 可生成场景中物体与物体之间的AO信息

缺点:

  • 缺少单一物体的细节(可调整参数提高烘焙细节,但同时烘焙纹理的数量和尺寸以及烘焙时间也会增加)
  • 只能烘焙静态的物体,动态物体无法进行烘焙获得AO信息

SSAO优缺点

优点:

  • 不依赖场景复杂度,效果质量依赖于最终图片像素大小(屏幕空间的分辨率)
  • 实时计算,可用于动态场景
  • 可控性强,灵活性强,操作简单

缺点:

  • 性能消耗非常昂贵,远超上边两种方法
  • 理论上AO质量要比上述两种离线烘焙的要差

SSAO性能消耗

性能消耗的主要方面

AO法向半球的随机采样
请添加图片描述

  • 采样数为64时,意味着每个像素都要在法向半球中随机采样64次

双边滤波的多重采样

下图中白色部分为实际输出的AO,黑色部分为1减之后的效果,能更清晰地对比出模糊的效果
请添加图片描述
请添加图片描述

  • 相比于高斯模糊,能够保证边界的清晰,但是消耗也更高

AO核心采样消耗说明

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

  1. 使用for循环进行半球随机向量的采样,if、for结构对GPU的计算性能并不友好(原因参考本文
    请添加图片描述
  2. 采样数(上图中_SampleKernelCount,针对for循环的次数)过低会导致效果较差。以64为例,1334×750的分辨率,每个像素循环计算64次,合计需要133475064次AO核心计算
  3. 循环体的重采样,采样数为64时每个像素计算需要采样64次来求得屏幕深度值法线值请添加图片描述

滤波采样消耗说明

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

  1. C#后期脚本中,Blit两次(横向和纵向),合计调用两次滤波渲染Pass
    请添加图片描述
  2. 单一滤波渲染Pass中的多重采样,包括7次主纹理采样和7次屏幕像素的法线信息采样,每个像素合计14次纹理采样
    在这里插入图片描述

作业

实现SSAO效果

在这里插入图片描述

基础SSAO效果
在这里插入图片描述

消除自阴影
在这里插入图片描述

增加范围判定
在这里插入图片描述

增加AO权重,双边滤波模糊
在这里插入图片描述

与其他算法比较(待补充)

(其他算法的实现待补充)

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-09 12:01:51  更:2021-09-09 12:02:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/30 1:34:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码