1453 字
7 分钟
【CG】基于图像的光照 Image-based Lighting(实时渲染)

在看这一篇文章之前你需要有前置知识:我的另一篇文章“【CG】辐射度量学 & PBR”。
这篇文章很大程度上参考了知乎上 Ubp.a大佬 的文章1

基于图像的光照 Image-based Lighting#

在基于物理的渲染中,想要获得非常好的渲染效果往往需要使用光线追踪,或者全局光照技术, 但是这些技术在实时渲染中往往非常复杂且实现起来非常困难。但如果只考虑光源的直接光照,渲染出来的效果又往往非常平淡。而 基于图像的光照(IBL) 则提供了一种简单的方式而提升了非常好的渲染效果。

IBL 通过将一张 cube map 或者 sphere map 贴图作为光源,它的每个像素都可以代表一个入射光。而对于一个着色点来说, 在这个着色点的法线方向的半球上,我们需要对cube map或者sphere map进行采样,我们让采样结果作为入射光 Li(p,ωi)=cubeMapSampling(p,ωi)L_i(p,\omega_i) = cubeMapSampling(p,\omega_i),然后计算反射方程(如果没有自发光项)。

Lo(p,ωo)=∫Hfr(p,ωi,ωo)Li(p,ωi)n⋅ωidωiL_o(p,\omega_o) = \int_{\mathcal{H} } f_r(p,\omega_i,\omega_o)L_i(p,\omega_i) n\cdot \omega_i d\omega_iLo(p,ωo)=∫H(kdfd+fs)Li(p,ωi)n⋅ωidωiL_o(p,\omega_o) = \int_{\mathcal{H} } (k_df_d+f_s)L_i(p,\omega_i) n\cdot \omega_i d\omega_i

根据积分的线性性我们将积分拆成一个漫反射项和镜面反射项。

Lo(p,ωo)=∫HkdfdLi(p,ωi)n⋅ωidωi+∫HfsLi(p,ωi)n⋅ωidωiL_o(p,\omega_o) = \int_{\mathcal{H} } k_df_dL_i(p,\omega_i) n\cdot \omega_i d\omega_i+\int_{\mathcal{H} } f_sL_i(p,\omega_i) n\cdot \omega_i d\omega_i

简化为

Lo(p,ωo)=Ld(ωo)+Ls(ωo)L_o(p,\omega_o) = L_d(\omega_o)+L_s(\omega_o)

而一旦在实时渲染中涉及到采样,直接来说这个方法是不可行的,所以在实时渲染中,我们需要对这个积分做一些近似,或者进行一些预计算, 把复杂的积分都先计算好,我们会分别预计算漫反射积分和镜面反射积分。

Irradiance Map#

慢反射项为

Ld(ωo)=∫HkdfdLi(ωi)n⋅ωidωiL_d(\omega_o) = \int_{\mathcal{H} }k_df_dL_i(\omega_i)n\cdot \omega_i d\omega_i

将与积分无关的项提出来

Ld(ωo)=ρπ∫HkdLi(ωi)n⋅ωidωiL_d(\omega_o) = \frac{\rho}{\pi}\int_{\mathcal{H} }k_dL_i(\omega_i)n\cdot \omega_i d\omega_i

其中

kd=(1−F)⋅(1−metallic)k_d = (1 - F) \cdot (1 - metallic)

其中 F 是菲涅尔项,而 FF 项包含了半程向量,而半程向量与入射角有关,所以不能提出到积分外部,所以我们需要对 kdk_d 做一些简化

kd≈F0+(max{1−roughness,F0}−F0)(1−(n⋅ωo))5k_d \approx F_0+(max\left \{ 1-roughness,F_0 \right \}-F_0 )(1-(n\cdot \omega_o))^5

此时 kdk_d 项与积分变量无关了

Ld(ωo)≈kdρπ∫HLi(ωi)n⋅ωidωiL_d(\omega_o) \approx k_d\frac{\rho}{\pi}\int_{\mathcal{H} }L_i(\omega_i)n\cdot \omega_i d\omega_i

展开

Ld(ωo)≈kdρπ∫02π∫0π2Li(ωi)cosθsin⁡θdθdϕL_d(\omega_o) \approx k_d\frac{\rho}{\pi} \int_{0}^{2\pi}\int_{0}^{\frac{\pi}{2}}L_i(\omega_i)cos\theta \sin\theta d\theta d\phi

现在的积分值只取决于法向 nn,在法线方向上的半球上决定了入射光的值。

所以我们可以使用一个 cube map 以提供光照来预计算这个积分,最后得到另一个cube map,这个新的cube map我们称作irradiance map。 要求解这个积分我们可以使用蒙特卡洛积分

均匀采样#

我们可以在半球上的角度进行角度空间的均匀采样,并假设 ϕ\phi 和 θ\theta 是独立的那么 它们在蒙特卡洛积分中的联合概率密度为

p(θ,ϕ)=p(θ)⋅p(ϕ)=1π/2⋅12π=10.5π⋅2πp(\theta, \phi) = p(\theta) \cdot p(\phi) = \frac{1}{\pi/2} \cdot \frac{1}{2\pi} = \frac{1}{0.5\pi \cdot 2\pi}

所以

Ld(ωo)≈kdρπ1N1N2∑iN1∑jN2Li(θi,ϕj)cosθisin⁡θip(θi,ϕj)L_d(\omega_o) \approx k_d\frac{\rho}{\pi}\frac{1}{N_1N_2} \sum_{i}^{N_1}\sum_{j}^{N_2}\frac{ L_i(\theta_i,\phi_j)cos\theta_i \sin\theta_i}{p(\theta_i,\phi_j)}

代入化简有

Ld(ωo)≈kdρπ1N1N2∑iN1∑jN2Li(θi,ϕj)cosθisin⁡θiL_d(\omega_o) \approx k_d\rho\pi\frac{1}{N_1N_2} \sum_{i}^{N_1}\sum_{j}^{N_2} L_i(\theta_i,\phi_j)cos\theta_i \sin\theta_i

余弦权重采样#

使用余弦权重采样的 PDF 是 p(ω)=cos⁡θπp(\omega) = \frac{\cos\theta}{\pi} 就有

Ld(ωo)≈kdρπ1N∑iNLi(ωi)cos⁡θcos⁡θπ=kdρ1N∑iNL(ωi)L_d(\omega_o) \approx k_d\frac{\rho}{\pi}\frac{1}{N}\sum_{i}^{N}\frac{L_i(\omega_i)\cos \theta}{\frac{\cos\theta}{\pi}}=k_d\rho\frac{1}{N}\sum_{i}^{N}L(\omega_i)

Speular#

在镜面反射部分中,镜面反射不仅取决于法线 nn,还取决于观察方向 vv 以及材质的粗糙度 α\alpha。这意味着如果你想预计算,你需要一个五维的表格(法线3D + 观察方向2D + 粗糙度1D),这在实时渲染中是不可接受的。

我们参考了 games2022 中的描述 对于镜面反射的 BRDF 它非常满足使用下面这个近似公式的使用条件

∫Ωf(x)g(x)dx≈∫ΩGf(x)dx∫ΩGdx⋅∫Ωg(x)dx\int_{\Omega} f(x)g(x)dx \approx \frac{\int_{\Omega_G}f(x)dx}{\int_{\Omega_G}dx}\cdot\int_{\Omega}g(x)dx

所以我们对积分做出一个拆分

Lo(p,ωo)≈∫ΩfrLi(p,ωi)dωi∫Ωfrdωi⋅∫Ω+fs(p,ωi,ωo)n⋅ωidωiL_o(p,\omega_o) \approx \frac{\int_{\Omega_{f_r}}L_i(p,\omega_i)d\omega_i}{\int_{\Omega_{f_r}}d\omega_i}\cdot\int_{\Omega^+}f_s(p,\omega_i,\omega_o)n\cdot \omega_i d\omega_i

使用蒙特卡洛积分

Lo(p,ωo)≈(∑k=1NLi(p,ωk)(n⋅ωk)∑k=1N(n⋅ωk))(1N∑k=1Nf(p,ωk,ωo)(n⋅ωk)p(ωk,ωo))L_o(p,\omega_o) \approx \left( \frac{\sum_{k=1}^{N} L_i(p,\mathbf{\omega}_k)(n\cdot \omega_k)}{\sum_{k=1}^{N}(n\cdot \omega_k)} \right) \left( \frac{1}{N} \sum_{k=1}^{N} \frac{f(p,\mathbf{\omega}_k, \mathbf{\omega_o}) (n\cdot \omega_k)}{p(\mathbf{\omega}_k, \mathbf{\omega_o})} \right)

预滤波环境光 (Pre-filtered Environment Radiance)#

注意到约等号右边的第一项是对 BRDF 中的 NDF 区域中所有的入射光的积分再归一化,这个操作就相当于对IBL 这张图进行 filtering, 在图上的任何一个点上,取这个点周围的一个范围进行平均操作。这个范围由roughness 决定,我们可以通过固定的 roughness 来预计算多张 cube map 并且使用 mipmap 进行保存,根据物体不同的 roughness 在不同的 mipmap 中进行插值获取 L 值 我们就是通过约等号右边的第一项进行预计算

Part 1=∑k=1NLi(p,ωk)(n⋅ωk)∑k=1N(n⋅ωk)\text{Part 1} = \frac{\sum_{k=1}^{N} L_i(p,\mathbf{\omega}_k)(n\cdot \omega_k)}{\sum_{k=1}^{N}(n\cdot \omega_k)}

BRDF LUT#

我们处理完了第一项,还有一项我们没有处理。我们知道 fs=D(h)F(ωo,h)G(l,ωo)4(n⋅ωo)(n⋅ωi)f_s = \frac{D(h)F(\omega_o, h)G(l, \omega_o)}{4(n \cdot \omega_o)(n \cdot \omega_i)},并且 GGX 重要性采样的标准 PDF 是 p(h)=D(h)(n⋅h)4(ωo⋅h)p(h) = \frac{D(h)(n \cdot h)}{4(\omega_o \cdot h)} 我们将其代入第二项有

I≈1N∑k=1ND(hk)F(ωo,hk)G(ωi(k),ωo)(ωo⋅hk)(n⋅ωo)D(hk)(n⋅hk)4(ωo⋅hk)I \approx \frac{1}{N} \sum_{k=1}^{N} \frac{\frac{D(h_k)F(\omega_o, h_k)G(\omega_{i}^{(k)}, \omega_o)(\omega_o \cdot h_k)}{(n \cdot \omega_o)}}{\frac{D(h_k)(n \cdot h_k)}{4(\omega_o \cdot h_k)}}

消掉 D(hk)D(h_k),化简得:

I≈1N∑k=1NF(ωo,hk)G(ωi(k),ωo)⋅4(ωo⋅hk)2(n⋅ωo)(n⋅hk)I \approx \frac{1}{N} \sum_{k=1}^{N} F(\omega_o, h_k) \frac{G(\omega_{i}^{(k)}, \omega_o) \cdot 4(\omega_o \cdot h_k)^2}{(n \cdot \omega_o)(n \cdot h_k)}

其中 F(ωo,hk)=F0+(1−F0)(1−ωo⋅hk)5F(\omega_o, h_k) = F_0 + (1 - F_0)(1 - \omega_o \cdot h_k)^5
我们令 Fbase=(1−ωo⋅hk)5F_{base} = (1 - \omega_o \cdot h_k)^5,则 F=F0(1−Fbase)+FbaseF = F_0(1 - F_{base}) + F_{base} 代入公式

I≈1N∑k=1N[F0(1−Fbase)+Fbase]G(ωi(k),ωo)(ωo⋅hk)(n⋅ωo)(n⋅hk)I \approx \frac{1}{N} \sum_{k=1}^{N} \left[ F_0(1 - F_{base}) + F_{base} \right] \frac{G(\omega_{i}^{(k)}, \omega_o)(\omega_o \cdot h_k)}{(n \cdot \omega_o)(n \cdot h_k)}

最后展开

I≈F0⋅(1N∑k=1N(1−Fbase)G(ωi(k),ωo)(ωo⋅hk)(n⋅ωo)(n⋅hk))⏟Scale+(1N∑k=1NFbaseG(ωi(k),ωo)(ωo⋅hk)(n⋅ωo)(n⋅hk))⏟BiasI \approx F_0 \cdot \underbrace{\left( \frac{1}{N} \sum_{k=1}^{N} (1 - F_{base}) \frac{G(\omega_{i}^{(k)}, \omega_o)(\omega_o \cdot h_k)}{(n \cdot \omega_o)(n \cdot h_k)} \right)}_{\text{Scale}} + \underbrace{\left( \frac{1}{N} \sum_{k=1}^{N} F_{base} \frac{G(\omega_{i}^{(k)}, \omega_o)(\omega_o \cdot h_k)}{(n \cdot \omega_o)(n \cdot h_k)} \right)}_{\text{Bias}}

终于! 我们得到了最后的公式

I≈F0×Scale+BiasI \approx F_0 \times \text{Scale} + \text{Bias}

其中 Scale 和 Bias 我们可以通过预计算将其存储在一张只有两个通道(R,G)的纹理中,Scale存放在r通道bias存放在g通道,将 xx 轴(U 坐标)映射为 cos⁡θv\cos\theta_v (n⋅ωon \cdot \omega_o), yy 轴(V 坐标)映射为 粗 Roughness,这张纹理我们称为 BRDF LUT
下面是一张 BRDF LUT

最后实现后类似这种效果

参考#

Footnotes#

  1. 深入理解 PBR/基于图像照明 (IBL) ↩

  2. games202-高质量实时渲染 ↩

【CG】基于图像的光照 Image-based Lighting(实时渲染)
https://blog.cglab.top/posts/cg-image-based-lighting/
作者
Artichoke
发布于
2026-03-22
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取

最后更新于 ,距今已过 216 天

部分内容可能已过时