Real-time Global Illumination

全局光照不仅要考虑直接光照,还要考虑间接光照。

RSM

Reflective Shadow Maps

  • 首先,我们怎么知道光源直接照到了哪些地方呢

    借助 Shadow Map。这个时候从 Shadow Map 上的每个像素对应的场景中的 Area 都会被当成次级面光源去照亮点 p。

  • 其次,我们怎么知道一个次级面光源对着色点 p 的光照贡献呢

如果对 p 的半球采样很多射线不会打到次级面光源上,造成浪费

因此对次级面光源的每个点计算对 p 的影响然后累计,也就是由 dw 转换成 dA

那么对 p 而言,需要多少个次级面光源呢

像有些点明显不会对 p 造成影响的点就不用考虑,可以将 p 投影到 shadow map 上,找 shadow map 中 p 周围的点,考虑这些点的影响,通常取 400+ 个。

RSM 需要存储 Depth 深度,这是 Shadow Map 原本就存储的。除此之外还有,世界坐标来判断距离(算Shading的时候需要使用),反射物的法线(计算cos项),光源的辐射通量。

通常用于手电筒上,覆盖范围小不需要太大的 RSM

缺点

  • 有多少个直接光源就需要多少个RSM,多光源开销大。

  • 无法考虑Visibilty项,不够真实

  • 假设反射物都是Diffuse,假设 shadow map 中 p 周围的点实际上也在 p 周围

  • 最后RSM的采样率和质量的平衡问题,这是所有采样方法都有的问题

LPV

LPV 将场景分成小格子,每个小格子记录各个方向光的 Radiance,用球谐函数表示(通常只用 2 阶)。

与 RSM 一样,不考虑 Visibility

当格子不够小时会出现漏光现象,即 step 4 中 p 对 q 的照亮。格子通常不会很小,可能比墙都厚,所以 step 3 的迭代 4、5 次就可以了。

VXGI

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 物体,则考虑分成多个圆锥

SSAO

Screen Space Ambient Occlusion

在屏幕空间内,对于全局光照的近似

假设1:每个点接收的间接光照都是一个常数,与之前的 BlingPhong 模型很像,但是不是每个方向的间接光照都能接收到。

假设2:是 Diffuse 物体

  • 左边 kA 是每个点的平均可见性
  • 右边 Li 是常数(假设1),brdf 是常数(假设2)

因此只需要求 kA 就行了

我们考虑 screen space 情况下,在着色点周围随机取几个点,因为 camera 视角会存储 depth,所以可以判断周围的点是否能被看见,从而估计着色点的 visibility

只有不可见部分超过一半时才考虑 AO

HBAO

Horizon based ambient occlusion

SSAO 研究时 Camera 并不会存各个点的法线,所以只是对视角方向的半球采样。

如今知道法线后,可以根据视角方向和法线方向夹角加权考虑,并且考虑范围距离问题,不会出现误遮挡现象。

SSDO

Screen Space Directional Occlusion

希望达到最后一张的效果,黄色光会打到蓝色物体之上

AO 假设间接光照来自很远的地方,因此对着色点的处理主要依据红圈

DO 假设间接光照来自很近的地方,因此对着色点的处理主要依据黄圈

SSDO 与 Path Tracing 有点像,p 随机射出一条光线,遇到障碍物则是间接光照,没遇到则是直接光照

那么如何求 p 击中的障碍物呢,方法与 SSAO 相同。

问题:

只能表示小范围全局光照

Screen Space 下会丢失信息,当看不见左侧黄块时就无法处理

SSR

Screen Space Reflection

也可以理解为 Screen Space Ray Tracing

考虑镜面反射的 SSR,我们需要计算像素反射的颜色是什么。

此处光线步进,因为是 Screen Space,我们没法通过之前的 SDF 来得到安全距离从而步进,因此只能一步一步走。

为了加速,采取与 TCP 拥塞窗口类似的算法

首先将 Shadow Map 分层,上一层某个点记录下一层对应区域的深度最小值。如果在高层没有交点,则对低层对应区域无交点,这样可以直接跨过一片区域。

如果最精细的步长没有交点,则下一步增加步长。如果有则减小层级并计算该层级。

SSR我们前面提到,它其实就是一种简略的Path Tracing,自然Path Tracing能得到的效果它都能得到,比如:

  1. Sharp and blurry reflections:

    锐利的反射和模糊的反射,这其实就是镜面反射和Glossy的反射,用不同的BRDF就能实现,我们前面提到过。

  2. Contact Hardening:

    这种现象会导致距离仿射平面近的地方反射锐利,而远的地方模糊。这是由于BRDF的反射锥形造成的,距离越远,锥体的范围也就越大,那计算光线贡献的范围也就会变大,自然也就模糊了,这是很正常的现象,因为正确的BRDF就是会得到这种现象。

  3. Specular elongation:

    SSR也可以做各项异性的反射,如图所示,反射效果被拉长了,这就是各向异性的BRDF导致的结果。 只要考虑了正确的BRDF,这些效果SSR都可以实现。

  4. Roughness and Normal

好处:

  • 对于Glossy和Specular效果有较好的表现

  • 较好的质量

  • 对BRDF采样无需考虑衰减,并且考虑了 Visibilty

问题:

  • 仍然是 Screen Space 的问题,没有屏幕之外的信息,所以看不见的手掌并不会显示在地面反射中

  • 仍然需要假设被反射的物体(手)是 Diffuse 的
  • SSR 本质上是一种Path Tracing,所以对反射材质(地板) 是 Diffuse 的物体比较难做