Games202笔记——Real-time-Global-Illumination(1)

Glossy情况下的PRT

既然是图形学,那么我们先摆一个渲染方程在这

现在我们认为p点已知,同时把渲染方程写成light和light transport形式,如下

注意到light transport项因为BRDF的关系,同时和入射方向和出射方向有关,意味着从任何一个不同的方向看,都会得出一组不同的向量,也就是说,PRT的结果现在是一个关于出射方向$\omega_o$的函数,如下所示

这样的话我们不如把light transport后的预计算结果视为一个矩阵,即

也就是把不同o得到的vector摆在一起

PRT的问题

1.SH不适合做高频(不是不能,阶数太多)

2.预计算也就意味着场景被固定住了

3.大量的预计算数据存储

Wavelet

Wavelet也是一系列基函数,其定义在一个图像块上,不同的小波定义域不同,下图所示的是Haar wavelet

image-20210515185627873

差不多得了开新东西开新东西

三维空间中的全局光照(Global illumination,GI)

传统的光栅化方法完全无法处理间接光照的问题,对于传统的Blin-Phong模型,GI通常用一个hack来解决,即增加一个Ambient项模拟全局光照,但是这种方法一点都不真实,我们还是需要一个全局光照的技术光追闭嘴

不是光追,咱还真的不能嗯用光线反弹,得用别的方法

我们可以认为每一个发生反射的表面都视为一个光源,那么全局光照可以理解为主光源和所有次级光源共同对场景作用的结果。

为了得到一个点的间接光照我们需要知道什么?我们需要知道以下两件事:

1.场景中又哪些次级光源,也就是说哪里会被光源照到,很显然Shadow Map就能告诉我们这些

2.每一个次级光源的贡献是多少?这部分问题的实质是解一个渲染方程

全局光照是不关心观察方向的,但是众所周知渲染方程没有出射方向就解不了,这个问题应该如何解决呢?我们提出一个大胆的假设:我们认为所有的反射物都是diffuse的,也就是说BRDF是常数,从哪个方向看都是一样的。这样场景中有哪些次级光源,次级光源从哪个方向上照射点p就解决了

Reflective Shadow Maps(RSM)

RSM的实现

首先回顾一下辐射度量学的三个基础概念

image-20210516010051643

我们可以将一个光源对p点着色的贡献的计算从立体角微元转化为光源面积的微元,如图所示

image-20210516010334978

这样渲染方程就被转化为了

$q\to p$指q点到p点的radiance,我们如何解的radiance的大小?

对于diffuse的情况,我们有结论$f_r=\rho/\pi$,而$L_i=f_r·\cfrac{\Phi}{dA}$,其中$\Phi$是光通量

把上两式带入,我们就消去了dA,实际上我们不用关心光源的面积

这样我们就知道了一个次级光源如何照亮着色点

同时我们还有一个观察:离着色点较近的次级光源往往会带来比较大的贡献,这里我们假设在SM上离得近的两点在实际距离上也较近,因此我们在采样SM上的次级光源的时候可以在近点增加采样次数,远点减小采样次数,通过类似的采样方案可以极小的减少采样的次数,带来效率上的提升

这种方法对于类似手电筒这种光源非常的友好,现在也经常被使用

RSM的特点

优点:

​ 1.很好实现

缺点:

​ 1.凡是SM有的问题它都有

​ 2.因为不算反射物到着色点的遮挡,看起来会不真实

Light Propagation Volumes(LPV)

思考下面这个看起来似乎不用思考的问题:在做间接光照的时候,如果我可以获得一个点从所有方向来的radiance,我们才能做间接光照,对吧?

LPV方法基于特别重要的物理事实,即radiance在传播的过程中总保持直线且不会改变。

LPV的要点是把场景分成3D的网格,每一个网格称为体素(Voxel),我们都知道间接光照的来源是场景中光的反射,现在我们想要知道经过类似的反射之后,场景中每一个体素内的光强是多少。

LPV的实现涉及很多的问题,接下来仅针对LPV的实现逻辑进行讲解。
LPV的实现分为以下几个步骤:

1.和RSM类似的,我们需要知道场景中哪些点可以作为次级光源

2.这些点需要被放到体素里面,学名注入(injection)

3.在三维的网格中传播radiance

具体来讲,对于第一步的次级光源判断,我们仍然可以用RSM,同样也可以靠采样来获得一系列次级光源

第二步注入,工业界的做法是生成一张3d texture来记录信息,对于每一个点我可以计算出radiance在每个方向上的分布,这是一个球面函数,可以用SH近似,一般在工业界只使用两阶

第三步我们对于每个网格,都可以计算从六个面传播过来的radiance,并使用SH近似,迭代若干次, 直到整个网格稳定下来。

这种方法听起来非常美好,那么代价是什么呢?

就比如它本质还是忽略了场景遮挡,所以是存在“穿墙照亮”的情况的(light leaking)

Voxel Global Illumination(VXGI)

VXGI和RSM一样是two-pass的算法,他和RSM的区别是什么呢?

首先其把整个场景划分成了一个个格子(想象乐高),其次划分存在层次结构(参考kd树),这样每一个次级光源就是一个体素,而不是一个像素

第二点是不同于LPV,radiance只传播一次,VXGI认为光打在场景表面会辐射出一个光锥,并对这个光锥进行cone tracing,由此可见比LPV慢,但也因为这个特性,其支持反射物表面是glossy的

因为圆锥会越传播越大,所以对于不同的距离可以在不同的层级进行查询,效率会高很多

如果是diffuse的情况,我们可能需要trace一个巨大的圆锥,这里我们选择几个小圆锥一起追踪,如图所示

image-20210516170906079

VXGI的效果还是很不错的,就是开销有点大

欢迎关注我的其它发布渠道