【GAMES202】Real-Time Global Illumination(screen space)1—实时全局光照(屏幕空间)1

一、Real-Time Global Illumination(in 3D cont.)

上篇只介绍了RSM,这里我们还会简要介绍另外两种在3D空间中做全局光照的方法,分别是LPV和VXGI。

1.Light Propagation Volumes (LPV)

首先我们知道Radiance在传播过程中是不会被改变的,这点我们都知道。

其次LPV将空间划分成了许多小格子,也叫Voxel(体素)。而这些Voxel就是用来传播间接光照的Radiance的。我们很容易知道直接光照,参考RSM的思路。然后通过知道哪些格子是次级光源来计算每个格子接受到的Radiance,这就是LPV的基本思路。

第一步,找到直接光打到的表面,这步和RSM无区别,当然,有多少光源就需要多少RSM。其次,也不是必须把所有被直接光打到的表面都当作次级光源,可以用采样的方式,我们之前都说过。这样我们就得到了一系列次级的虚拟的光源。

得到了次级光源我们就可以把它们注入到相应的格子里,变成格子的属性,这样我们就知道每个格子往各个方向的Radiance初始值都是多少,而这是个空间的分布,自然我们就可以用前面提到的SH压缩它。(工业界常用2阶) 

第三步就是传播了,那么Radiance如何传播呢?很简单,次级光源所在的格子里有向四周传播的Radiance,而Radiance又是按直线传播的。自然,一个格子6个面,穿过它上表面格子的Radiance自然就会被它上面的格子接受到,其它面的Radiance同理,同样其它的格子里的Radiance分布也可以用SH所表示(这里和RSM一样,我们不考虑传播过程中的Visibilty)。如此不断迭代,直到最后整个网格稳定下来。(差不多迭代4,5次)

第四步自然就是渲染了,对于任意的着色点,我们都知道它们在哪个格子里,我们还知道它们的Incident Radiance,就可以渲染了。 

当然,这其中会有问题,如上图所示。场景中的几何比划分的格子小的时候就会很容易发生这种情况。如图p点为直接光照照亮的点,它是次级光源,显然它右边有一面墙,它绝对不可能照到墙右边的部分,但由于LPV的Radiance是用格子存储的,我们会认为这个格子里都是相同的Radiance。于是墙右边被照亮了,这显然是错误的。但如果把格子划分的非常非常细,虽然可以解决这种问题,但随之而来的自然是存储量问题,以及Radiance传播的计算量问题。不过当然,我们可以自适应划分一些格子的分辨率,如工业界常用的Cascade方法。

2.Voxel Global Illumination(VXGI)

VXGI和RSM相同,是一个双Pass的算法(LPV相当于4Pass)。VXGI把场景彻底离散化成了体素(参考MineCraft/乐高积木)。并且还会把这些格子组成一个树形结构,有不同的层级。

所以与RSM不同的是,RSM的次级光源是每一个小片,而VXGI的次级光源是体素。

其次VXGI的第二个Pass与RSM和LPV都不同,它的第二个Pass从Camera出发,打出Camera Ray,而假设当Camera Ray打到某个Glossy材质对应的片元所在位置,自然就会变成一个锥形的分布,然后这个锥形与之前得到的次级光源所在体素相交,就可以知道这个着色点得到的贡献是多少了。

Pass1,计算直接光照,和RSM和LPV类似,但这里我们可以不再认为所有反射物都是Diffuse的了 ,这里我们会在Voxel体素中的表面上记录一个入射光的分布(如上图绿色所示),还会记录该表面的用来反射的法线分布(如上图橙色所示),并且我们还知道这个表面是Diffuse还是Glossy的自然就可以计算出它的出射分布,这比我们直接假设默认Diffuse的方法会准确一些。由此我们还可以在小格子记录分布后整合到更高的层级,形成一个层次结构。

Pass2从Camera出发发射的Camera Ray(假如是Glossy)经过着色点后会被反射成圆锥,我们叫它Ray cone,它会随着传播的距离增大而变大。之后计算它与哪些体素相交,再把贡献加在一起就可以了。不过既然Ray cone范围会越来越大,我们可以直接在之前体素的层次结构中找对应的层级体素记录的分布信息即可。这就是VXGI的基本思路。

而对于Diffuse物体,VXGI的发明者们的做法是用差不多8个圆锥来覆盖半球以此近似Diffuse的情况。

当然对于VXGI,它也有一些问题。首先我们要对整个场景进行体素化,这是需要预处理的,而如果是动态物体,那每一帧都要实时体素化,显然会非常慢。以及对于Diffuse的情况,圆锥增多,查询次数自然也会增多。

二、Real-Time Global Illumination (screen space)

屏幕空间限定了我们获取信息的范围,也就是说我们得到的信息仅仅能从屏幕上能看到的东西上获取,相当于一个后处理。而对于做GI之前,那我们能得到的信息自然也就是直接光照了。

Screen Space Ambient Occlusion (SSAO)—屏幕空间环境遮蔽

左图:带有AO  |  右图:无AO

环境遮蔽(Ambient Occlusion) —简称AO,简单的说就是物体缝隙间光线难以到达的地方会有些发暗的现象,如上图的对比图。

那么屏幕空间的环境遮蔽是什么呢?其实就是全局光照的一种近似,因为AO本身就是由全局光照造成的。并且我们只能通过在屏幕中获取的看到的可见信息来做,如法线,深度等。

(1)Idea

那么SSAO是怎么做的呢?首先,我们不知道着色点的间接光照是什么,但是我们可以假设它们的四面八方的间接光照是一个常数,也就是我们之前说的Blinn-Phong模型那样。

但是,相比于Blinn-Phong模型好的地方在于,虽然我们仍然假设四面八方的间接光照是一个常数,但不见得所有着色点都能接收到它,也就是我们考虑了Visibility,这样就会有几何的遮挡关系。

(2) Theory

左:AO较少 | 右:AO较多

从数学上来理解SSAO,自然就要回到咱们的渲染方程上来,同时回顾一下我们经常用的上图所示的约等式,它可以把Visibility项拆出去。

可以看到,拆出Visibilty项后就是上图蓝框里所示的部分,下面的积分就是π。那整个其实就是一个加权平均了,我们设为kA,它的值自然就是0~1。其次橙色框的部分实际上就是我们事先给定的数,BRDF是Diffuse的,所以是常数,间接光我们一开始也给定的是常数,所以就固定下来了。

(3)Deep understanding*(可忽略)

一个更深的理解,我们上一步已经说了拆出的Visibility项其实就是f(x)的加权平均。那我们更进一步,SSAO这个公式完全就可以理解成,在g(x)的覆盖范围内,f(x)的平均值是多少。而我们之前说过这个约等式要想准确符合的条件,这里由于g(x)我们上面说过是常数,那就肯定是smooth的,所以这个约等式是成立且准确的。

还有一个问题,我们拆分之后,按照拆分的约等式,为什么本来是对dω积分,现在变成了对cosθdω积分呢?如何解释这个问题呢?

这里我们引入另外一个概念,Projected solid angle—投影立体角,我们之前说立体角实际上对应了单位球面上一个面积,那自然,投影立体角是投影后的立体角,对应的就是单位球下单位元的一块面积。对投影立体角积分得到的自然就算单位圆的面积,也就是π*1*1,也就是π。所以我们上面写成对cosθdω积分实际上是对投影立体角积分,这也就解释了我们为什么能如此拆分。

(4)Compute

上面的Deep understanding只是为了更深层次的理解SSAO,实际上单从渲染方程上来看很简单,如上图,因为我们已经认定了BRDF和Li都是常数,那就都提出去就好了,积分中只剩Visibility项。

那现在我们怎么计算这个值呢?SSAO提供了一个方法,那就是在任何一个着色点的整个球的体积内采样,然后判断这些采样点能不能被着色点看到。那怎么判断采样点在物体内外呢?这要通过深度图来判断,深度图是我们在屏幕上看到的最浅深度,一定程度上描述了场景的几何,这时如果我们把采样点投影到Camera上,那么采样点的深度Zs和Z-Buffer中记录的最浅深度Z做比较,就可以知道采样点是不是在物体内了,若Zs>Z,那就说明采样点在物体内,反之则在物体外。

当然有一种意外情况,如上图中间的情况,几何体有一个拐角,但是由于我们的Z-Buffer记录的是最浅深度,所以无法区分这种情况。

还有个问题,我们判断整球没有意义,因为法线另外半球着色点是肯定看不到的,所以判断整球会造成一个很大的浪费,我们事实上只需要判断法线方向半球就足够了,但是在SSAO被发明的那个年代还无法从屏幕上获取法线,所以人们采取了另外一种方法:只有看不到的采样点(上图所示红点)占比超过50%的时候才考虑AO问题,然后只计算另一半的红点占比就可以了。因为产生AO一定程度上就是红点过半导致的。

当然,即使是这样,因为没有法线而导致的无法cos进行加权还是会导致结果没那么准确,只是一个近似。

(5)False occlusions

SSAO也会产生一些False occlusion的问题,如上图,近处的石凳对远处的地板居然产生了AO,这显然是不对的,两个物体离的这么远,石凳是不可能对地板产生遮蔽的。究其原因,是因为在地板球上的一些采样点投影到屏幕上之后和石凳的最浅深度比较的时候大于石凳的最浅深度,于是错误的认为是红点,所以产生了遮蔽。

如果减小采样半径,一定程度上可以解决问题,但是自然可能也会丢失一些True occlusion。也就是原本该遮挡的地方没有遮挡,一切都是取舍问题。

(6)Other

 • 采样问题

SSAO仍然做了采样,那么自然就有我们前面提到的所有采样方法共有的问题,采样点数量的取舍,越多的采样点自然意味着更好的质量,但会牺牲速度。

人们通常在使用SSAO时会使用较少的采样点生成一个Noisy的AO,然后再做一遍模糊,这样就能得到相对较好的结果,因为实际玩游戏的时候很少有人会盯着AO看。

 • HBAO—Horizon Based Ambient Occlusion

之前我们说,因为SSAO在发明的时候人们在屏幕上很难获取到法线,但是现在可以,于是就有了HBAO。有了法线,我们自然就知道要在哪半球采样,然后算之前的红点占比。

其次,有法线,我们还可以对各个方向进行加权了,就可以得到相对来说更准确的值。其次,HBAO不会有SSAO的False occlusion问题,因为它真的考虑了一定范围距离的问题。 


参考

GAMES202_Lecture_08 (ucsb.edu)

Lecture8 Real-time GLobal Illumination (screen space)_哔哩哔哩_bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/119078.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis事务为什么不支持回滚

Redis事务中过程中的错误分类两类: 在exec执行之前的错误,这种错误通常是指令错误,比如指令语法错误、内存不足等... --> 在开始事务后,传输指令时,遇到这种错误,Redis会给出Error错误提示,…

lv3 嵌入式开发-4 linux shell命令(进程管理、用户管理)

目录 1 进程处理相关命令 1.1 进程的概念 1.2 查看进程的命令 1.3 发送信号命令 2 用户管理相关命令 2.1 用户管理相关文件介绍 2.2 用户管理相关命令介绍 1 进程处理相关命令 1.1 进程的概念 进程的概念主要有两点: 进程是一个实体。每一个进程都有它自己…

基于java Swing 和 mysql实现的飞机订票系统(源码+数据库+ppt+ER图+流程图+架构说明+论文+运行视频指导)

一、项目简介 本项目是一套基于java Swing 和 mysql实现的飞机订票系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、项目文档、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过…

PostgreSQL命令行工具psql常用命令

1. 概述 通常情况下操作数据库使用图形化客户端工具,在实际工作中,生产环境是不允许直接连接数据库主机,只能在跳板机上登录到Linux服务器才能连接数据库服务器,此时就需要使用到命令行工具。psql是PostgreSQL中的一个命令行交互…

【Linux】线程安全-信号量

文章目录 信号量原理信号量保证同步和互斥的原理探究信号量相关函数初始化信号量函数等待信号量函数释放信号量函数销毁信号量函数 信号量实现生产者消费者模型 信号量原理 信号量的原理:资源计数器 PCB等待队列 函数接口 资源计数器:对共享资源的计…

【Linux】进程的优先级

我们都知道进程等待需要cpu处理的,那就需要一个数据结构来记录要被cpu处理的进程,那这些进程是按一个什么样的方式在这个结构中进行等待呢?下面就要谈到进程的优先级了: 目录 一、进程的优先级的概念 二、查看进程的优先级 2.1…

【javaweb】学习日记Day8 - Mybatis入门 Mysql 多表查询 事务 索引

之前学习过的SQL语句笔记总结戳这里→【数据库原理与应用 - 第六章】T-SQL 在SQL Server的使用_Roye_ack的博客-CSDN博客 【数据库原理与应用 - 第八章】数据库的事务管理与并发控制_一级封锁协议_Roye_ack的博客-CSDN博客 目录 一、多表查询 1、概述 (1&#…

Spring-Kafka生产者源码分析

文章目录 概要初始化消息发送小结 概要 本文主要概括Spring Kafka生产者发送消息的主流程 代码准备&#xff1a; SpringBoot项目中maven填加以下依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent&…

大数据技术原理与应用学习笔记第1章

黄金组合访问地址&#xff1a;http://dblab.xmu.edu.cn/post/7553/ 1.《大数据技术原理与应用》教材 官网&#xff1a;http://dblab.xmu.edu.cn/post/bigdata/ 2.大数据软件安装和编程实践指南 官网林子雨编著《大数据技术原理与应用》教材配套大数据软件安装和编程实践指…

Liunx系统编程:信号量

一. 信号量概述 1.1 信号量的概念 在多线程场景下&#xff0c;我们经常会提到临界区和临界资源的概念&#xff0c;如果临界区资源同时有多个执行流进入&#xff0c;那么在多线程下就容易引发线程安全问题。 为了保证线程安全&#xff0c;互斥被引入&#xff0c;互斥可以保证…

Java-泛型

文章目录 Java泛型什么是泛型&#xff1f;在哪里使用泛型&#xff1f;设计出泛型的好处是什么&#xff1f;动手设计一个泛型泛型的限定符泛型擦除泛型的通配符 结论 Java泛型 什么是泛型&#xff1f; Java泛型是一种编程技术&#xff0c;它允许在编译期间指定使用的数据类型。…

操作视频的开始与暂停

调用 ref.current.play() 方法来播放视频&#xff1b; 如果视频需要暂停&#xff0c;我们调用 ref.current.pause() 方法来暂停视频。 通过 useRef 创建的 ref 操作视频的开始与暂停 当用户点击按钮时&#xff0c;根据当前视频的状态&#xff0c;我们会开始或暂停视频&…

ip地址、LINUX、与虚拟机

子网掩码&#xff0c;是用来固定网络号的&#xff0c;例如255&#xff0c;255,255,0&#xff0c;表明前面三段必须为网络号&#xff0c;后面必须是主机号&#xff0c;那么怎么实现网络复用呢&#xff0c;例如使用c类地址&#xff0c;但是正常子网掩码是255&#xff0c;255,255,…

GB28181学习(二)——注册与注销

概念 使用REGISTER方法进行注册和注销&#xff1b;注册和注销应进行认证&#xff0c;认证方式应支持数字摘要认证方式&#xff0c;高安全级别的宜支持数字证书认证&#xff1b;注册成后&#xff0c;SIP代理在注册过期时间到来之前&#xff0c;应向注册服务器进行刷新注册&…

vue从零开始学习

npm install慢解决方法:删掉nodel_modules。 5.0.3:表示安装指定的5.0.3版本 ~5.0.3:表示安装5.0X中最新的版本 ^5.0.3: 表示安装5.x.x中最新的版本。 yarn的优点: 1.速度快,可以并行安装 2.安装版本统一 项目搭建: 安装nodejs查看node版本:node -v安装vue clie : np…

C语言练习8(巩固提升)

C语言练习8 编程题 前言 奋斗是曲折的&#xff0c;“为有牺牲多壮志&#xff0c;敢教日月换新天”&#xff0c;要奋斗就会有牺牲&#xff0c;我们要始终发扬大无畏精神和无私奉献精神。奋斗者是精神最为富足的人&#xff0c;也是最懂得幸福、最享受幸福的人。正如马克思所讲&am…

明厨亮灶监控实施方案 opencv

明厨亮灶监控实施方案通过pythonopencv网络模型图像识别算法&#xff0c;一旦发现现场人员没有正确佩戴厨师帽或厨师服&#xff0c;及时发现明火离岗、不戴口罩、厨房抽烟、老鼠出没以及陌生人进入后厨等问题生成告警信息并进行提示。OpenCV是一个基于Apache2.0许可&#xff08…

01-虚拟机安装Windows Server操作系统

1、创建并配置虚拟机 2、安装操作系统 找到windows Server镜像 等待安装 3、设置密码

数据结构之单链表java实现

基本概念 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中指针链接次序实现的。和数组相比较&#xff0c;链表不需要指定大小&#xff0c;也不需要连续的地址。 单链表的基本设计思维是&#xff0c;利用结构体的设置&#xff0c…

滑动窗口实例5(水果成篮)

题目&#xff1a; 你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而&#xff0c;农场的主人设定了一些严格的规矩&#xff0c;你必须按…