SSAO与HBAO学习笔记(持续改进)
简介
环境光遮蔽是计算场景中每一点是如何接受环境光的。而实时渲染中的环境光遮蔽则是对此的模拟。
我们这里实现比较常见的SSAO和HBAO,一个表面点的AO的计算则是对其法线所在半球面的可见性的积分
Apˉ=1π∫ΩVpˉ,ω^(n^⋅ω^)dω\displaystyle A_{\bar {p}}={\frac {1}{\pi }}\int _{\Omega }V_{{\bar {p}},{\hat {\omega }}}({\hat {n}}\cdot {\hat {\omega }})\,\operatorname {d} \omega Apˉ=π1∫ΩVpˉ,ω^(n^⋅ω^)dω
实时计算的时候离散的积分就好了
SSAO
SSAO的原理比较简单,其流程比较适合DeferredLighting,一个点的
其实现步骤如下
- 获取到当前帧的深度图Depth,能获取到法线贴图Normal更好,不能的话直接用ddx和ddy计算也行
- 对深度图上的每个像素,计算出其ViewSpace的坐标P0,在其法线所在半球面上采样点N个点,计算出这些点的ViewSpace坐标P1 ~ PN,并再次计算出P1 ~ PN的NDC,并采样得到这些点的真实深度值,并重建出真实的ViewSpace坐标V1 ~ VN
- 对于P1 ~ PN与V1 ~ VN的大小,当V大于P的时候,该点被遮挡,可以根据遮挡的距离给出遮蔽的遮挡积分的权重
- 最后对所有的采样点都做了遮挡计算后平均,得到当前点的AO值
实现上我们是直接抄的Unity实现版本,从中比较有意思的点是GPU上的伪随机,因为我们需要在单位半球面上随机采样
//From Next Generation Post Processing in Call of Duty: Advanced Warfare [Jimenez 2014]
// http://advances.realtimerendering.com/s2014/index.html
float InterleavedGradientNoise(float2 pixCoord, int frameCount)
{const float3 magic = float3(0.06711056f, 0.00583715f, 52.9829189f);float2 frameMagicScale = float2(2.083f, 4.867f);pixCoord += frameCount * frameMagicScale;return frac(magic.z * frac(dot(pixCoord, magic.xy)));
}// Pseudo random number generator with 2D coordinates
float UVRandom(float u, float v)
{float f = dot(float2(12.9898, 78.233), float2(u, v));return frac(43758.5453 * sin(f));
}
这基本是在GPU上能找到的比较好用的随机数生成方法了
HBAO
相比于SSAO,HBAO则是扩展了采样点的启发性,参考[2],
环境光遮蔽的半径定义在ViewSpace,我们实现中也是
- 获取到当前帧的深度图Depth,能获取到法线贴图Normal更好,不能的话直接用ddx和ddy计算也行
- 对深度图上的每个像素,计算出其ViewSpace的坐标P0,在其法线所在半球面上采样点
- 当前点Tangent-Bitagent平面上随机朝着比如4个方向采样
- 当前点Tagent-Normal的随机一个方向上做类似RayMatching的操作,第一步还做一个随机的Offset,每个步进,都获取到对应深度的ViewSpace上的点,计算每个采样 S1S_{1}S1 的权重,总权重 WAO=0
- AO(S1)=sinΘ(S1)−sintAO(S_{1})=\sin\Theta(S_{1})-\sin tAO(S1)=sinΘ(S1)−sint
- WAO+=W(S1)AO(S1)WAO+=W(S_{1})AO(S_{1})WAO+=W(S1)AO(S1)
- 最后把所有采样得到的权重跟采样次数平均一下就可以得到最终的AO效果
具体详细的流程还是把PPT上的内容抄一遍比较好。
实现中我们采用了跟SSAO一样的伪随机函数
一般AO的实现后都使用Horizontal和Vertical的Blur进行降噪。
还没有尝试过Temporal的方式去降噪,因为AO本来就是低频的信息,所以非常适合这种Temporal的方法
有兴趣的小伙伴可以看看我的简单实现 https://gitee.com/alienity/SRPAmbientOcclusion
引用
[1] https://zhuanlan.zhihu.com/p/46633896
[2] https://developer.download.nvidia.cn/presentations/2008/SIGGRAPH/HBAO_SIG08b.pdf
SSAO与HBAO学习笔记(持续改进)相关推荐
- 重拾CCNA,学习笔记持续更新ing......(4)
重拾CCNA,学习笔记持续更新ing......(4) 路由器作用功能的经典解说(笑)(非原创) 假设你的名字叫小不点,你住在一个大院子里,你的邻居有很多小伙伴,在门口传达室还有个看大门的李大爷,李大 ...
- Admin.NET管理系统(vue3等前后端分离)学习笔记--持续更新
我的学习笔记 - 9iAdmin.NET 欢迎学习交流 (一)前端笔记 1.1 关于.env的设置 1.2 关于路由模式问题 1.3 关于 vue.config.ts 1.4 关于 打包(pnpm r ...
- 专升本 计算机 公共课学习笔记(持续更新中...)
计算机公共课学习笔记 第一章 计算机基础知识(30分) 1.计算机概述 计算机(Computer)的起源与发展 计算机(Computer)也称"电脑",是一种具有计算功能.记忆功能 ...
- JS逆向学习笔记 - 持续更新中
JS逆向学习笔记 寻找深圳爬虫工作,微信:cjh-18888 文章目录 JS逆向学习笔记 一. JS Hook 1. JS HOOK 原理和作用 原理:替换原来的方法. (好像写了句废话) 作用: 可 ...
- CSS(3)学习笔记——持续更新
本篇皆是本人长期记录并整理出来的笔记,如有记录得不对的地方,欢迎探讨.记录的很少,将不断学习不断补充. 1 选择器 CSS(3)中提供的选择器手册(w3school):http://www.w3sch ...
- 计算机网络:学习笔记(持续更新)
文章目录 前言 1.1 计算机网络基本概念 什么是计算机网络? 什么是网络协议? 1.2 计算机网络结构 计算机网络结构 网络边缘 接入网络(物理介质) 网络核心(核心网络) Internet结构 1 ...
- 机器学习学习笔记-持续学习(Continual Learning/ Life-long Learning)
任务: 将旧任务学习的知识应用到新的任务上,同时在旧任务上的表现不会出现太大的损失. 问题: (1)将旧任务的知识利用,从而更快适应新任务. (2)在学习新任务的同时在旧任务上的表现不会出现太大下降. ...
- typescript-----javascript的超集,typescript学习笔记持续更新中......
Typescript,冲! Typescript 不是一门全新的语言,Typescript是 JavaScript 的超集,它对 JavaScript进行了一些规范和补充.使代码更加严谨. 一个特别好 ...
- csp php,CSP学习笔记(持续学习更新)
CSP--Content Security Policy 大佬光辉照耀我-学习链接 百度百科:CSP指的是内容安全策略,为了缓解很大一部分潜在的跨站脚本问题,浏览器的扩展程序系统引入了内容安全策略(C ...
最新文章
- Linux上隐藏进程名(初级版)
- [零基础学JAVA]Java SE应用部分-27.Java IO操作(01)
- AHK 中 % 符号的用法
- python配置日志的几种方式
- 【网络编程】之七、select聊天室
- uniapp踩坑指南之坑多到写不完
- python set集合_玩转Python集合,这一篇就够了!
- 2022 软件测试工程师面试题小结【附带答案】
- 安装mysql时报错:计算机中丢失VCRUNTIME140_1.dll,亲测有效
- ubuntu开机直接进入命令行模式
- 网上银行“安全登录控件”分析
- 机器学习编译入门课程学习笔记第一讲 机器学习编译概述
- 微型计算机与接口技术总结,微机原理与接口技术课程总结
- 品管(QC)七大手法
- 安信可nbiot模块_案例丨安信证券服务化平台实践
- android 随手记 摄像头录像
- 金华市电子计算机学校,金华市第十四届中小学生计算机竞赛结果
- python 豆瓣源安装_python pip使用豆瓣源技巧和pip配置文件更改豆瓣源
- C语言中函数的一些基本内容
- 基于javaweb个人网站论坛的设计与实现(源码、论文、毕业设计、数据库文件)