转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=507

上一篇“游戏中基于物理的渲染(一)”中介绍了反射方程和Lambert,本篇将介绍基于物理的光源部分。

精确光源

游戏中经典的光源有point, directional和spot,这些局部光源都可以抽象成“精确光源”的概念,表示一个方向确定、大小为无穷小的光源。由于要计算的是到达表面点时的光照,所以不考虑从光源到表面之间的衰减。因此,精确光源都可以用颜色$\mathbf{c}_{light}$和光源方向向量$\mathbf{l_c}$这两个参数来表示。光源颜色$\mathbf{c}_{light}$的确切定义是,白色的Lambert表面被平行于表面法线($\mathbf{l_c}=\mathbf{n}$)的光照照亮的颜色。

如何计算这个光源对点的贡献呢?这里需要先引入一个叫做微面光源的概念。顾名思义,微面光源是一个非常小的面光源,中心是$\mathbf{l_c}$,张角是$\varepsilon$。该微面光源照亮表面的一个点可以用$L_{tiny}(\mathbf{l})$来表示。$L_{tiny}(\mathbf{l})$有两个性质:

$\forall\mathbf{l}|\angle(\mathbf{l}, \mathbf{l_c})>\varepsilon, L_{tiny}(\mathbf{l})=0$

$if \mathbf{l_c}=\mathbf{n}, \mathbf{c}_{light}=\frac{1}{\pi}\int_{\Omega} L_{tiny}(\mathbf{l}) (\mathbf{n} \cdot \mathbf{l}) d\omega_i$

第一个性质表示如果入射方向和$\mathbf{l_c}$的夹角大于$\varepsilon$, 那么亮度为0。第二个性质是从$\mathbf{c}_{light}$的定义而来,白色表面使得$\mathbf{c}_{diff}=1$,结合上文所说的反射方程和Lambert,就可以得出性质二。由于$\mathbf{c}_{light}$要求$\mathbf{l_c}=\mathbf{n}$,所以$\mathbf{c}_{light}$也表示了当$\varepsilon$趋近 于0的时候的极限,也就是

$if \mathbf{l_c}=\mathbf{n}, \mathbf{c}_{light}=\lim_{\varepsilon \to 0}(\frac{1}{\pi}\int_{\Omega} L_{tiny}(\mathbf{l}) (\mathbf{n} \cdot \mathbf{l}) d\omega_i)$

因为$\mathbf{l_c}=\mathbf{n}$而且$\varepsilon \to 0$,我们可以认为$\mathbf{n} \cdot \mathbf{l}=1$,所以得到:

$\mathbf{c}_{light}=\lim_{\varepsilon \to 0}(\frac{1}{\pi}\int_{\Omega} L_{tiny}(\mathbf{l}) d\omega_i)$

也就是

$\lim_{\varepsilon \to 0}(\int_{\Omega} L_{tiny}(\mathbf{l}) d\omega_i) = \pi \mathbf{c}_{light}$

把微面光源带入一般的BRDF,得到的就是当趋近于0时的极限:

$L_0(\mathbf{v})=\lim_{\varepsilon \to 0}(\int_{\Omega} \rho(\mathbf{l},\mathbf{v}) \otimes L_{tiny}(\mathbf{l}) (\mathbf{n} \cdot \mathbf{l}) d\omega_i)=\rho(\mathbf{l_c}, \mathbf{v}) \otimes \lim_{\varepsilon \to 0}(\int_{\Omega} L_{tiny}(\mathbf{l}) d\omega_i)(\mathbf{n} \cdot \mathbf{l_c})$

所以

$L_0(\mathbf{v})=\pi \rho(\mathbf{l_c}, \mathbf{v}) \otimes \mathbf{c}_{light} (\mathbf{n} \cdot \mathbf{l_c})$

入你所见,刚才引入的微面光源已经从公式中消失,剩下的部分又回到了熟悉的几个项。

本系列的第二篇论述了基于物理渲染的光源公式推导,下一篇将讲解BRDF部分,也就是$\rho(\mathbf{l_c}, \mathbf{v})$。