笔记

SSAO介绍

AO

环境光遮蔽,AmbientOcclusion。一种模拟光线到达物体的能力和粗略的全局方法。

SSAO

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

历史

AO在Siggraph 2002年会由ILM展示
2007年,Crytek将SSAO应用于孤岛危机

原理

  1. 获取深度、法线缓冲
  2. 利用深度值,反推每个像素在世界空间中的三维位置
  3. 利用法线,得到法向半球
  4. 利用法向半球产生随机向量,计算像素随机后的坐标(多次采样)
  5. 与采样点的深度进行比较,加权到AO中
  6. 后期(模糊等)

SSAO算法实现

获取深度、法线缓冲数据

C#

private void Start(){cam = this.GetComponent<Camera>();cam.depthTextureMode = cam.depthTextureMode | DepthTextureMode.DepthNormals;
}

获取相机组件
深度纹理模式设置为 带深度带法线

Shader


这里的UV是屏幕空间的UV

重建相机空间坐标

具体参考:https://zhuanlan.zhihu.com/p/92315967


构建法向量正交基


tangent其实是半球面上 随机的一个向量(随机的方法参考下文)

AO采样核心


第二步:
_SampleKeneralRadius : 采样半球的半径长度
第三步:
因为都是在观察空间下进行的计算,所以得到randomPos后,乘以投影矩阵,再视图映射即可得到相应的屏幕坐标
rclipPos :即是球面上的点

SSAO优化

1. 随机正交基

应用于求法向半球的正交基时,其第二步生成随机变量。

_ScreenParams.xy 是屏幕的长宽,除以4是为了对应4x4像素的贴图。
因为i.uv 的增量是 1/_ScreenParams.x 或 1/_ScreenParams.y ,noiseUV增量也即 x或y增0.25,也即Noise贴图走一个格子。

2. AO累加平滑优化——范围判断

如果从天空盒的位置产生半球,采样到深度差很大的球体遮挡会产生ao,导致天空的像素上有阴影

加一个深度差绝对值的阈值判断,能够避免采样到深度差太大的无关遮挡
原本:

改成:

3. AO累加平滑优化——自身判断

4. AO累加平滑优化——AO权重


随机点的xy 越靠近的,权重越大

5. 模糊

烘培AO

三维建模软件烘培

烘培AO到纹理

优点:

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

缺点:

  1. 操作较其它方式繁琐,需要对模型进行UW处理,再进行烘焙到纹理。
  2. 不利于整体场景的整合(如3DMax烘焙到纹理,只能选择单一物体,针对整体场景的处理工作量巨大);
  3. 增加AO纹理贴图,不利于资源优化(后期可通过其它纹理通道整合资源);
  4. 只有物体本身具有AO信息,获取物体之间的AO信息工作量巨大

游戏引擎烘培AO

优点:

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

SSAO优缺点

优点:

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

SSAO性能消耗

主要在两个方面

AO法向半球的随机采样

  1. For结构代码
  2. 采样数:64 x 长 x 宽次AO核心计算
  3. 每个像素需要采样64次屏幕深度值、法线值

双边滤波的多重采样

作业

实现SSAO效果

原图

AO图

混合图

使用其它AO算法实现进行对比

HBAO原理

全称Horizon-Based Ambient Occlusion,水平基准环境光遮蔽。

  1. 将360度分等份,在各个方向上做RayMarching,同时对这些方向加入随机旋转。下图以分4个方向来做

  2. 对于其中一个方向。再RayMarching过程中,得到一个最大的horizon angle(水平角)

  3. 根据点P及其法线,计算出切面角tangent angle

  4. 通过horizon angle 和 tangent angle,计算得出AO。(注意这里角度的范围,是实现的细节)

  5. 对其它三个方向相同操作,将AO值加起来平均后,得到最终点P的AO值

HBAO效果实现

核心代码:

fixed4 frag_Ao (v2f i) : SV_Target{//采样获得深度值和法线值float3 viewNormal;float linear01Depth;float4 depthnormal = tex2D(_CameraDepthNormalsTexture,i.uv);DecodeDepthNormal(depthnormal,linear01Depth,viewNormal);//获取像素相机屏幕坐标位置float3 viewPos = reconstructViewPos(i.uv);//获取像素相机屏幕法线,法相z方向相对于相机为负(so 需要乘以-1置反),并处理成单位向量viewNormal = normalize(viewNormal) * float3(1, 1, -1);float deltaAngle = 2.0 * UNITY_PI / _RayAngleStep;// 1/屏幕分辨率宽w , 1/屏幕分辨率高hfloat2 InvScreenWH = _ScreenParams.zw - 1.0;//_RayMarchingRadius 屏幕空间的采样半径float rayMarchingStepSize = _RayMarchingRadius/_RayMarchingStep; //采样核心float ao = 0;for(int j = 1; j <= _RayAngleStep; j++){float uvAngle = deltaAngle * j;float maxHAngle = _AngleBias;//两个叉乘求tangent线 float3 marchingDir =  float3(GetRayMarchingDir(uvAngle), 0.0f);float3 temp = cross(marchingDir , viewNormal);float3 tangent = cross(temp, viewNormal);float sinTangentAngle = length(tangent.z)/length(tangent);sinTangentAngle *= tangent.z > 0.0f ? 1.0f : -1.0f;for(int k = 1; k < _RayMarchingStep; k++){float2 deltaUV = round( marchingDir * rayMarchingStepSize * k) * InvScreenWH;float2 stepUV = i.uv + deltaUV ;float3 pointPos = reconstructViewPos(stepUV);float3 diffPos = pointPos - viewPos;float exist = (diffPos.z < -0.04 ? 1.0 : 0.0);//差值z需小于0,并且加一点bias//这个漏了,明显错误,想了好久float sinHAngle = length(diffPos.z)/length(diffPos) * exist;if(sinHAngle > maxHAngle){maxHAngle = sinHAngle;}}if(maxHAngle  > _AngleBias){ao += maxHAngle - sinTangentAngle;}}ao = ao / _RayAngleStep;float4 color;color = max(0.0, 1 - ao * _AOStrength);color.a = 1;return color;}

补充函数

inline float2 RotateDirections(float2 dir, float2 rot)
{return float2(dir.x * rot.x - dir.y * rot.y,dir.x * rot.y + dir.y * rot.x);
}inline float2 GetRayMarchingDir(float angle)
{float sinValue, cosValue;sincos(angle, sinValue, cosValue);return RotateDirections(float2(cosValue, sinValue), float2(1.0, 0));
}float3 reconstructViewPos(float2 uv)
{float3x3 proj = (float3x3)unity_CameraProjection;float2 p11_22 =  float2(unity_CameraProjection._11, unity_CameraProjection._22);float2 p13_31 =  float2(unity_CameraProjection._13, unity_CameraProjection._22);float depth;float3 viewNormal;float4 cdn = tex2D(_CameraDepthNormalsTexture, uv);DecodeDepthNormal(cdn, depth, viewNormal);depth *= _ProjectionParams.z;return float3((uv * 2.0 - 1.0 - p13_31) / p11_22 * (depth), depth);
}

HBAO效果

之前的SSAO

对比HBAO、SSAO

  1. HBAO性能是有较大提升的,更适用于移动端。HBAO采样数大量减少,如果一个像素采样4个方向,4个RayMarching的话,也即16个采样点。而SSAO 要64个采样点,相当于4倍。其实可以理解为HBAO的通过角度的大小,节约了一部分的采样点。
  2. 效果上看,HBAO近处的细节相比于SSAO,是会差一截的。原因是步进(RayMarching)是基于屏幕的,越近,像素点之间的信息就越少。

HBAO优化

1. 基础阈值

当sin(H)大于一个bias时,才有ao

2. 非连续问题

只有在半球区域内的遮挡才有效,与避免从天空盒采样到遮挡同理。

原HBAO

解决非连续问题后的HBAO

在代码中,加入阈值判断,可以看出远处墙体的阴影少了。

3. 衰减

离像素点越远的采样点,影响应该越小
使用公式:W(r)= 1 - r²

公式曲线

Per-Sample Attenuation: 逐采样衰减。考虑阈值内的各个采样点,分别乘以权重给出贡献。

Per-Sample Attenuation

原HBAO

添加衰减后的HBAO

加入了衰减后,可以发现阴影的扩散变小了,更紧凑了。

其它AO

GTAO,Bent Normal,AAO,TSSAO,VXAO,UE4的Distance Filed Ambient Occlusion

参考资料

https://www.bilibili.com/video/BV16q4y1U7S3?p=2
https://developer.download.nvidia.cn/presentations/2008/SIGGRAPH/HBAO_SIG08b.pdf
https://blog.csdn.net/puppet_master/article/details/82929708

【技美百人计划】图形 4.2 SSAO算法 屏幕空间环境光遮蔽(&HBAO)相关推荐

  1. 【TA-霜狼_may-《百人计划》】图形4.2 SSAO算法 屏幕空间环境光遮蔽

    [TA-霜狼_may-<百人计划>]图形4.2 SSAO算法 屏幕空间环境光遮蔽 @[TOC]([TA-霜狼_may-<百人计划>]图形4.2 SSAO算法 屏幕空间环境光遮蔽 ...

  2. 图形 4.2 SSAO算法 屏幕空间环境光遮蔽

    链接: SSAO算法 屏幕空间环境光遮蔽思维导图. SSAO算法 屏幕空间环境光遮蔽 SSAO介绍 什么是AO SSAO原理详解 SSAO介绍 SSAO原理 计算近似AO SSAO算法实现 比较与分析 ...

  3. 技美 百人计划 (图形)1.1渲染流程

    技美 百人计划 (图形) 图形 1.1 渲染流水管线2.1数学基础 很早之前就有关注百人计划这个系列的课程,也跟着看到了2.几的教学但是一直没有写笔记,最近看到百人计划已经快更新完毕了,决定从头看一遍 ...

  4. 技美 百人计划 2.1色彩空间

    技美 百人计划 2.1色彩空间 2.1色彩空间 色彩发送器 色彩的认知 光源是出生点,光源发射出光线,光线通过直射反射折射等路径最终进入人眼.但人眼接收到光线后,人眼的细胞产生了一系列化学反应,由此把 ...

  5. 【技美百人计划】图形 4.4 抗锯齿概论

    笔记 锯齿是怎么产生的 左图:想要的效果 右图:表现的效果 抗锯齿分类 ● 前向渲染: SSAA.MSAA.CSAA.RGSS等 ● 延迟渲染: FXAA.MLAA.SMAA等 ● 时域上的抗锯齿: ...

  6. 【技美百人计划】图形 4.5 Dof景深基础

    笔记 景深原理 ● 指相机对焦点前后相对清晰的成像范围,是一段三维空间. ● 针对相机成像产生的概念,肉眼也有类似的效果 景深遇到的问题 因为是基于深度图的实现,如果是半透明物体,则没有深度,要如何解 ...

  7. 【技美百人计划】图形 4.3 实时阴影介绍

    笔记 先讲两个概念 软阴影.硬阴影 硬阴影: ● 应用于点光源 ● 对于每一个像素,只需要检查该像素和光源之间是否有遮挡物存在即可,因此这种和像素一对一的可见性函数结果可以如同表面颜色一样,被存储在一 ...

  8. 【技美百人计划】美术 1.1.3 角色设计精要

    笔记 角色设计流程 设计流程: 角色设计流程: 确定角色关键词 ● 了解角色并找到那些让角色独一无二的关键词 ● 如这些角色的重要标识:世界观.背景.能力.职业.性格.喜好 EXP 小美: 设计之初: ...

  9. 【技美百人计划】美术 1.1 美术理论基础

    笔记 光影 光影:物体呈现在人们眼前的时候,不同的受光面其明暗变化以及物体的影子 黑白灰 & 明暗五调子 黑白灰: 受光面为亮形成白,背光面为暗形成黑,其他的过渡为灰色 明暗五调子: ● 高光 ...

最新文章

  1. Linux下清空用户登录记录和命令历史的方法
  2. NS3_Tutorial 中文版: 第一章 简介 第二章 资源
  3. 基于 SpringBoot2 + MybatisPlus 的商城管理系统(附源码)
  4. 使用Nexus私服代理其他maven仓库(jitpack、jcenter)
  5. Python excle数据读写
  6. 简单的php文件_简单的php文件上传(实例)
  7. html page背景图片,html – Fullpage.js背景图片
  8. BZOJ4372: 烁烁的游戏【动态点分治】
  9. 算法不会,尚能饭否之排序——直接插入排序(Insert sort)
  10. String.intern()使用总结
  11. sqlServer对内存的管理
  12. python自带idle_使用自带的IDLE
  13. SUSE Linux 15 If ‘netstat‘ is not a typo you can use command-not-found to lookup the package...
  14. Celery实现短信注册接口
  15. 美国贝勒大学计算机科学专业怎么样,美国贝勒大学好吗
  16. 应用案例 | 2009 款北京现代伊兰特车换挡冲击故障诊断
  17. Log4j写日志文件使用详解
  18. VC中自定义IE浏览器
  19. 2018年总结和职场规划
  20. jasper支持哪些html标签,Jasper HTML输出宽度问题(示例代码)

热门文章

  1. 开发内功修炼网络篇电子书出炉!!!
  2. QGraphicsItem图元旋转缩放和自定义图元(三)
  3. java中的三目运算
  4. VS Nuget的使用
  5. CSS的px和em的区别
  6. 计算机科学与技术专业答辩形式,2016计算机科学与技术专业论文答辩范例.ppt
  7. 表单input标签type属性详解
  8. 刘强东的“百亿补贴” 被指“雷”声大雨点小
  9. 需要达到什么样的水平才能找到一份看起来不错的互联网实习?
  10. 杭电计算机学院2019年奖学金,关于计算机学院2019-2020学年国家励志奖学金评选的通知...