作者:i_dovelemon
日期:2020-01-04
主题:Rendering Equation,Irradiance Environment Map,Spherical Harmonic
引言
在实时图形渲染中,Global Illumination 是圣杯级的效果。为了实现这个效果,前辈们开发了很多的技术。但是这些技术大都只能用于静态物体上,对于动态的物体却不能很好的支持。所以,为了让动态的物体也有一点 GI 的效果,开发出了一系列的技术。今天,我们就来介绍其中一种技术:Diffuse Irradiance Environment Map。在游戏开发领域,一般称之为 Light Probe(注:当然 Light Probe 能够实现更多的效果,Diffuse 的 GI 是其中一种)。
Diffuse Irradiance Environment Map 是基于 Environment Map 来实现的。所以,它不会考虑阴影和模型本身的光照影响。同时,我们也只探讨光照中的 Diffuse 部分,即 Lambert BRDF 部分。
文章中会存在大量的渲染相关的术语,诸如 irradiance,radiance,solid angle 等等。我们假设你已经了解了这些基础性的概念知识,如果不是,PBRT [文献1] 是一个很好的参考资料。
本文将主要从两个方面来讲述:一个是传统的计算 Diffuse Irradiance Environment Map 的方法,我们称之为 Brute force;另外一种是基于 Spherical Harmonic 的方法。
背景知识
我们回顾下渲染方程,可以知道一个点在半球范围里面受到的 irradiance 为:
$E(\vec{n})=\int_{\Omega(\vec{n})}^{ }L(\vec{w})(\vec{n}\cdot\vec{w})d\vec{w} \ \ \ \ \ \ \ \ (1)$
也就是说,对于一个固定的 Environment Map (即 $L(\vec{w})$ 相同)来说,irradiance 只和 normal 有关。所以,我们可以通过预计算,将 Environment Map 对应的 Irradiance Environment Map 保存为一个和 normal 相映射的形式,然后通过顶点的 normal 来获取对应的 irradiance 信息。获取到 irradiance 信息之后,带入下面的公式,就能够得到最终需要显示的颜色值:
$B(\vec{p},\vec{n})=f(\vec{p})E(\vec{n}) \ \ \ \ \ \ \ \ (2)$
其中 $f(\vec{p})$ 表示的是 Diffuse 的 BRDF。
BruteForce 方法
公式(1)中计算 irradiance 的方法,是一个在半球范围里面积分的形式,这种方式不存在解析解,没有办法直接去计算得到。但是,由于光照环境是通过 Environment Map 来表达的,我们可以将公式(1)转化为离散的形态,如下公式所示:
$E(\vec{n})=\sum_{i=0}^{N-1}L(\vec{w})(\vec{n}\cdot\vec{w})d(\vec{w})\ \ \ \ \ \ \ \ (3)$
其中,N 表示的是整张 Environment Map 上的所有像素的数量;$L(\vec{w})$ 表示的是在 $\vec{w}$ 方向上的 radiance;$d(\vec{w})$ 表示的是在 $\vec{w}$ 方向上像素的 solid angle。
这样,我们就有了一个方法来实际计算一个 normal 方向上的 irradiance 的值了。
我们知道了如何计算一个 normal 对应的 irradiance 的值,那么这个值该怎么保存了?很明显的,我们可以利用另外一张 Cubemap 来保存各个 normal 计算出来的对应的 irradiance 的值,而这个新的 Cubemap 就是 Diffuse Environment Irradiance Map。以下是整个过程的伪代码:
for pixel_iem in IrradianceEnvironmentMap n = GetNormal(pixel_iem) irradiance = 0 for pixel in EnvironmentMap L = GetRadiance(pixel) w = GetRadianceDir(pixel) dw = GetTexelSolidAngle(pixel) irradiance += L * max(