图形学渲染基础(7) 实时环境光照(Real-time Environment Mapping)

3,566 阅读13分钟

简介

全局光照(Global Illumination,GI) ,严格意义上指主光+完整的间接光下的光照效果,实际上只要有体现间接光效果(即使是部分效果)的光照都可称为 GI。本文的算法虽然是基于环境光这个角度出发的,但是所属范畴仍然可算 GI 方法。

GI 总体上分为两派:

  • 一派是通过一套统一标准的渲染流程把任何物体的 GI 计算出来,往往计算量极大但效果更加物理更加真实,典型的例子便是离线光线追踪
  • 另一派是把 GI 的效果看成一个个部分来组成,这样我们可以选择其中一些 GI 效果组合使用,适应不同的性能(往往计算量相对低些,尤其是实时渲染)的同时也能带来能接受的 GI 效果(虽然往往不是严谨的物理正确),典型的例子就是这篇博客所介绍的方法和另一些完全动态的 GI 方法(如 RSM、SSAO、SSRT)

基于图像的照明(IBL)

基于图像的光照(IBL) ,简单的说就是一类通过环境贴图(Environment Map)来保存某个物体的环境光信息,从而实现该物体的基于物理的物体渲染方法。

  • IBL 可用于 diffuse/glossy/specular 物体(基本上包含大部分物体了)渲染:这取决于环境贴图,环境贴图分辨率越大,那么所能表示高频信息就越多,从而越适合 specular 物体的渲染;而分辨率越低,所表示的信息更多是低频信息,则 diffuse 物体的渲染也足以满足,而且还能节省一定存储空间。
  • IBL 可以实现成动态环境光照:实时渲染出动态的环境贴图。有一定开销,一般只用于少量的specular物体。
  • IBL 可以实现成静态环境光照:预渲染环境贴图。需要环境光是静态的。 用 IBL 实现静态环境光照就有点类似 Light Map的做法了,区别在于 IBL 存的是静态环境光信息,Light Map 存的是接受静态环境光信息后的着色结果。

The Split Sum Approximation

那么通过环境光贴图实现IBL呢?本质上仍然是对shading point的渲染方程的求解问题,在这里所有的光照信息Li通过环境贴图给出,并且不考虑遮挡关系Visibility。

image.png IBL中最常见的算法便是基于 The Split Sum Approximation 的算法。 image.png 上图分别是glossy/specular物体的BRDF(左图)和diffuse物体的BRDF(右图)情况,可以看出:

  • 如果 BRDF 是 glossy/specular 的,那么它的 lobe 往往是花瓣状,即只有很小的积分域才能接受环境光。
  • 如果 BRDF 是 diffuse 的,那么它的 lobe 往往是均匀的半球状,即无论哪个方向的环境光打进来, fr函数的输出几乎没多少变化(甚至是个常数) 这让我们想起一个经典的近似公式 image.png 想让这个公式近似效果比较精确,那么需要满足以下一种或两种条件:
  • 积分域 ΩG 比较小 (对应Specular的lobe很小)
  • g(x)比较光滑,即变化不是很大 (对应Diffuse的fr变化不大) 于是渲染方程可以拆成两个部分分别进行求解(环境光积分、BRDF积分),后面会使用预计算的方法对两部分的计算分别进行优化。 image.png
  • Split Sum 方法和原始蒙特卡洛方法的图像效果几乎一模一样
  • 由于不用对环境贴图进行多重采样,性能开销大大减低了

预计算环境贴图

因为我们已经拥有一张环境贴图(无论是实时的还是预渲染的)来存储环境光信息了,为了计算环境光部分的积分,需要在 Ωfr范围内做多次光线采样。但是,可以有一个几乎等价但避免运行时多重采样的方式:预先对纹理进行滤波操作(模糊),我们只需要对滤波后的环境贴图采样一次光线方向就能得到积分。 image.png 当然,BRDF Lobe 的形状越尖锐,即环境光积分范围越小,就需要使用模糊程度更低的环境贴图;反之 BRDF Lobe 的形状越粗壮,即环境光积分范围越大,就需要使用模糊程度更高的环境贴图。

我们可以使用 MIPMAP技术 来生成不同Level的环境贴图,通过三线性插值(Trilinear Interportion)的方式来得出任何模糊程度且任何2D位置的环境光滤波结果。 image.png

预计算BRDF

我们先来回顾一下 Microfacet BRDF 的组成: image.png

  • F(l,h): 菲涅尔方程(Fresnel Equation),描述不同的表面角下表面所反射的光线所占的比率。
  • G(l,v,h): 几何函数(Geometry Function),描述微平面自成阴影的属性,即m = h的未被遮蔽的表面点的百分比。
  • D(h): 法线分布函数 (Normal Distribution Function),描述微面元法线分布的概率,即正确朝向的法线的浓度。即具有正确朝向,能够将来自l的光反射到v的表面点的相对于表面面积的浓度。 image.png 可以预想到,该BRDF 的积分结果依赖于三个参数:
  • F0(Fresnel项系数)
  • α (粗糙度 roughness)
  • θv(反射方向与法线的夹角,实际上决定了 θvhθvh、θhθh) 我们可以把 F0 项拆出来,让BRDF 积分拆成两个积分,但是这些积分都减少了一个依赖的参数 image.png 这样,对于相同的材质(相同的BRDF),我们就可以针对剩余两个依赖的参数 αα 、θvθv 建立一张 二维查询表image.png

预计算辐射度传输(PRT)

预计算辐射度传输(Precomputed Radiance Transfer,PRT)  是一类通过预计算辐射度传输的基于物理的物体渲染方法。所谓辐射度传输,可以理解成物体自身的阴影/AO和表面互反射等有关于光路传输的信息。因此 PRT 往往适用于动态光照下的静态物体/静态材质

  • PRT 可以实现静态环境光照:不仅预计算 transfer,还顺便预计算环境光部分(可以称为 radiance);这样就能以更低性能开销实现运行时基于物理的渲染,只是光照动态性会有所限制(但不一定完全静态
  • PRT 可以实现动态环境光照:仅预计算 transfer 部分 这里需要补充一下的是,在PRT之前,实时渲染的一大难题就是解决阴影和互反射问题,caustics现象就更不用说了,难上加难。主要难点在于这些物理现象要求对每个点的半球面求解入射光线的积分(渲染方程),这实在是一个很难实时完成的任务。PRT算法的核心有两个
  • 将环境光照用基底编码,如球谐光照方法;
  • 将入射光映射为包含阴影、反射等信息的transferred radiance,预先计算、存储起来,在实时渲染时将其直接应用到实时光照上;

球谐函数(SH)

对于任意一个函数来说,都可以用一系列的基函数的线性组合来表示,最典型的例子就是信号处理中所提到的傅里叶变换,傅里叶变换将f(x)表示成另一系列基函数(各种频率的正弦谐波)的线性组合: image.png 而 球谐(Spherical Harmonics,SH)  便是定义在球面上的一系列2D基函数,它与2D傅里叶序列有点相似,但非常适合球面函数 f(ω)(即参数为单位球面向量)。 image.png 上图是球谐函数的前n阶的图像化展示,每一阶上SH的频率是相同的,并且阶级越高频率越高,能表示的信息越详细。 如果要完全复原一个任意函数,我们需要无穷阶的 SH;而如果我们只要复原一个任意函数的近似(换句话说只重建出该函数的低频信息),那么我们完全可以只需要前几阶的 SH(包含 l=0,l=1,...,l=n 每一阶的所有基函数)。

想象我们在高等数学中学到的知识:泰勒公式是将一个在x=x0处具有n阶导数的函数f(x)利用关于(x-x0)的n次多项式来逼近函数的方法。可以把球谐函数对球面函数的逼近想象成f(x)泰勒展开的过程。

SH 基函数的形式比较复杂,这里不作过多描述,接下来介绍用SH作为球面函数的基函数的几点好处:

  • 基函数之间具有正交性(orthonormal) image.png
  • 通过 投影(Projection)  可以很方便得到 SH 系数(SH coefficients) image.png
  • 通过系数向量组与基函数组的点积(前n阶的基函数/系数共有 n*n 个)可以很方便重建球面函数 image.png
  • product projection:c(ω)=a(ω)b(ω)【两个球面函数想乘后的球面函数SH系数情况】 image.png
  • 支持插值,对 SH 系数的插值相当于对重建的函数值的插值。
  • 旋转不变性(rotational invariance),对函数 f的旋转 RSH等价于对 f(ω)的自变量的旋转 R3D:

球谐光照

球谐光照(SH Lighting)  的思路:将渲染方程分为两个球面函数(即 lighting function 和 transfer function),这些球面函数将使用 SH 方法来表示:

  • 对于环境光(lighting)部分,只需预先存储若干个 SH 系数而不必存储一整张环境贴图。
  • 对于传输函数(transfer function) 部分,只需预先存储若干个 SH 系数(diffuse情况下)或者矩阵(glossy情况下),预计算好传输率可以在实时渲染中以极低代价实现自阴影、互反射的效果。 QQ截图20211103143328.png 不过 SH Lighting 一般采用3阶SH,因此 SH 所能表示的 lighting 和 transfer 信息是低频的,只适用于 diffuse 和 glossy 的物体而不适用于 specular 的物体。

Diffuse 物体的球谐光照

Diffuse物体的渲染思路: image.png

Le 代表环境光;ρ为 BRDF 项;V为 Visibility(表示不被遮挡的程度,往往表现为自遮挡产生的阴影现象)。

  • 由于物体是 diffuse 的,因此它的 BRDF 将是一个常数 ρ(无论从哪个方向观察都得到相同的BRDF值),也因此 diffuse 物体的 Li 将是一个常量值,而不受参数 r影响
  • 对于 lighting 部分 L(ω),原本需要对 Environment Map 进行查询,而现在可以换成使用 SH 函数去表示:Le(ω)≈∑liBi(ω)Le(ω)≈∑liBi(ω)
  • 对于 transfer function部分T(ω)=V(ω)max(0,n⋅ω),也可以换成使用 SH 函数去表示:T(ω)≈∑TjBj(ω)

其中的Li和Ti分别Lighting部分和Transfer部分对应的SH系数向量,只要进行简单的向量点积即可以得到L(o)。

此时,我们可以理解成系数 li 代表了环境光照(lighting)的信息,而系数Ti代表了在某个顶点上光路传输(light transfer)的信息;整个模型预计算完成之后将会得到一个 lighting 系数向量模型顶点数量对应的 transfer 系数向量 image.png

Glossy 物体的球谐光照

Glossy物体的球谐光照思路如下: image.png 由于Glossy物体的BRDF不仅与入射角度有关而且还和观察角度有关,不同视角观察物体表面同一点会有不同的光照。因此 glossy 的 BRDF 将是四维的函数(参数不仅包含ω,还包含r),这次将 BRDF 算入 transfer,则 transfer function 将额外增加一个二维参数。上图中的Li和tij分别是Lighting和transfer function对应的的SH向量和矩阵。 预计算过程:

  1. 对整个环境光信息,预计算 lighting 的 SH 系数向量组 l⃗ l→,其中一个元素为:li=∫Ω+L(ω)Bi(ω)dωli
  2. 对每个顶点,预计算 light transfer 矩阵 TT,其中一个元素为:Tij=∫Ω+Bj(ω)Ti(ω)dω 、Ti(r)=∫Ω+T(r,ω)Bi(ω)dω 由于 Glossy 物体需要每个顶点存储一个矩阵 T,这使得空间开销略大,因此不太实用。 image.png

光照探针(Light Probe)

光照探针(Light Probe)  是一类场景 GI 方案。它在场景里设置若干个Probe点(可以理解成向四面八方探测光照的点),为每个 Probe 预计算出环境光信息后,在运行时通过物体周围的 Probe 信息来插值来得到物体此时受到的环境光。

实际上,PRT也算是一种基于Probe的GI方案:PRT物体上的每个顶点都是一个Probe,它所探测的环境光照信息将预计算为 SH 系数,然后 shading point 可以根据三角形的顶点对 SH 系数做重心插值从而得到该点的 SH 系数(即代表了环境光)。只是 PRT 的每个三角形顶点都是一个Probe,这些Probe综合起来完成了单个物体的 GI 效果;而一般的 Light Probe 方案是在场景中每隔一段空间放置一个Probe,这些Probe综合起来提供了场景中所有物体的 GI 效果。

不过 Light Probe 经常会遇到错误的 Bleeding 问题:受到几何上不应该存在光照关系的 Probe 影响,常见于墙壁遮挡的内外侧。

image.png

光照贴图(Light Map)

Light Map 一般记录的是受静态部分环境光后的着色结果,着色方法不限于Ray Tracing、辐射度、Shadow、环境光遮蔽(Ambient Occlusion,AO)等算法。

Light Map 方法实际上就是把环境光被分成了静态部分和动态部分,而 Light Map 记录的正是受静态部分环境光后着色结果,因此参与烘焙的物体(位置、形状、材质)和光照都应当是静态的,这样的局限性很大

总结

聪哥的归纳真的好!!!

  • IBL 是半动态的 GI 方法(环境光可动可静、动态物体、材质仅粗糙度参数可变),常用于 Specular 物体的渲染
  • PRT 是半动态的 GI 方法(环境光可动可静、即使静态环境光还可支持旋转、物体不可形变、静态材质), 常用于 Diffuse/Glossy 物体的渲染
  • Light Probe 是半动态的 GI 方法(静态环境光、动态物体), 实时给场景中任何物体提供合适的静态环境光信息
  • Light Map 是全静态的 GI 方法(静态环境光、静态物体),预先给场景中静态物体提供受环境光静态部分影响后的着色结果

参考