转载请注明出处为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})\)。