基于物理的渲染:基于图像照明(Image-based Lighting)


在基于物理的渲染方法之中,如果想获得非常好的渲染效果,则需要分析光线的传播来进行全局光照(直接光照与间接光照)的计算,但该方法所需要的计算代价是巨大的,“往往”无法支持实时的需要。相反,如果仅仅考虑光源的直接光照,虽然渲染速度提升,但是渲染质量却不尽如人意,而基于图像照明(IBL)就是这样一种处于两个“极端”之间的方法,把天空盒环境贴图上的颜色信息当做环境光源,通过对反射方程的近似计算,从而生成采样贴图,最终计算光照能量时仅仅需要去对这个贴图进行采样再加以计算即可,相比于完整的全局光照减轻了计算代价,同时也带来了不错的渲染质量的提升,以下本文便会详细介绍这样一种渲染技术。

1 预备知识

(在第一章中回顾一些简略的基础知识,详细讲解可以查看我的前几篇笔记)
根据learnopengl中定义,一般把满足如下三个条件的渲染称为基于物理的渲染:
1.基于微平面理论
2.使用基于物理的BRDF
3.保证能量守恒

1.1 微平面理论

所谓微平面理论(Microfacets Theory),就是从微观的角度去观察物体,并认为物体的表面在到达微观的尺度之后,都是由许许多多的更小的理想镜面所组成的。
当这些微小的理想镜面的法线方向较为集中一致的时候,从宏观角度来看,物体的镜面反射会比较明显,反之,当这些微小镜面的法线方向较为杂乱的时候,物体表面则会相对粗糙。如下图所示:
在这里插入图片描述
(可以看到,第一幅图的微平面的镜面法线方向比较集中,第二幅图中的微平面的镜面法线方向比较分散)
当然并不是所有的光都会被微表面直接反射的。当光线照射到物体表面时,一部分光线会与表面的许许多多的微小镜面发生镜面反射,另一部分光线则会折射进入物体内部,如下图:
在这里插入图片描述
当光线折射进入内部的时,会与物体的微小粒子不断发生碰撞并散射到随机方向,在碰撞的过程中一部分光线会被吸收转换为热能,还有一部分光线会因为散射方向的随机性重新离开表面,而这部分光线就恰好形成了漫反射。

1.2 反射方程与BRDF

具体来说,上述所讲的微平面理论会体现在反射方程当中的BRDF中。
首先回顾一下反射方程:
L o ( p , ω o ) = ∫ Ω + L i ( p , ω i ) f r ( p , ω i , ω o ) ( n ⋅ ω i ) d ω i L_{o}\left(p, \omega_{o}\right)=\int_{\Omega^{+}} L_{i}\left(p, \omega_{i}\right) f_{r}\left(p, \omega_{i}, \omega_{o}\right)\left(n \cdot \omega_{i}\right) \mathrm{d} \omega_{i} Lo(p,ωo)=Ω+Li(p,ωi)fr(p,ωi,ωo)(nωi)dωi
其中 p p p为光线照射到的点, L i L_i Li为入射光, L o L_o Lo为观察方向的出射光, ω i 和 ω o \omega_i和\omega_o ωiωo又分别代表入射方向与出射方向(观察方向), ( n ⋅ ω i ) (n\cdot\omega_i) (nωi)代表宏观物体法线与入射光的夹角。 f r f_r fr即BRDF,用来衡量入射光radiance与出射光irradiance的比例。因此直观理解的反射方程,即来自观察方向 ω r \omega_r ωr上的反射光,是由所有不同方向上入射光贡献得到的,而不同方向入射光对反射方向 ω r \omega_r ωr的贡献程度则由物体表面材质属性决定,所以乘上了一个BRDF函数来体现这一点。
正如一开始所说,对于基于物理与微平面理论的特点,就体现在BRDF之上,一般使用的微平面模型为Cook-Torrance模型,其BRDF为:
f r ( ω i , ω o ) = k d f l a m b e r t + f s f_{r}\left(\omega_{i}, \omega_{o}\right)=k_{d} f_{lambert}+ f_{s} fr(ωi,ωo)=kdflambert+fs
其中:
f l a m b e r t = ρ π f s = F D G 4 ( N ⋅ V ) ( N ⋅ L ) k s = F k d = ( 1 − k s ) ∗ ( 1 − m a t a l n e s s ) \begin{aligned} &f_{lambert} =\frac{\rho}{\pi} \\ &f_{s} =\frac{F D G}{4(N \cdot V)(N \cdot L)}\\ &k_{s} =F \\ &k_{d} =(1 - k_s)*(1-matalness) \\ \end{aligned} flambert=πρfs=4(NV)(NL)FDGks=Fkd=(1ks)(1matalness)
f l a m b e r t 和 f s f_{lambert}和f_s flambertfs分别代表漫反射项和镜面反射项, k s k_s ks为微平面理论当中直接与微平面进行镜面反射的光线所占百分比,由菲涅尔项 F F F决定,而 k d k_d kd则是折射进物体内部所占的百分比,之所以在 1 − k s 1-k_s 1ks之后乘上了1-metalness (0<metalness<1),是因为当金属程度越高,镜面反射占比也就越高,而折射进入物体内部的就越少,同时这里的 k d + k s ≤ 1 kd+ks \leq1 kd+ks1也一定程度上保证了能量守恒。对于漫反射项 f l a m b e r t f_{lambert} flambert和镜面反射项 f s f_s fs在之前的笔记中有详细推导证明,这里就不再展开。接下来简单介绍一下F,D,G这3个函数

1.2.1 菲涅尔项 F

F F F为菲涅尔项,用来描述光线反射率与 入射光和法线的夹角的关系,精确计算太过复杂,这里一般用近似形式:
F ( h , v , F 0 ) = F 0 + ( 1 − F 0 ) ( 1 − ( h ⋅ v ) ) 5 F\left(h, v, F_{0}\right)=F_{0}+\left(1-F_{0}\right)(1-(h \cdot v))^{5} F(h,v,F0)=F0+(1F0)(1(hv))5
其中:
F 0 = l e r p ( 0.04 , ρ , m e t a l n e s s ) F_0=lerp(0.04,\rho,metalness) F0=lerp(0.04,ρ,metalness)
v v v为观察方向, h h h为微平面法向。 ρ \rho ρ为物体表面的颜色值,一般由贴图采样决定。

1.2.2 法线分布函数 D

D是法线分布函数,衡量微平面法线的分布情况,物理含义为每单位面积,每单位立体角下所有法向为 h h h的微平面的面积。
这里采用GGX/Trowbridge-Reitz作为法线分布函数:
D ( h ) = α 2 π ( ( n ⋅ h ) 2 ( α 2 − 1 ) + 1 ) 2 D(\mathbf{h})=\frac{\alpha^{2}}{\pi\left((\mathbf{n} \cdot \mathbf{h})^{2}\left(\alpha^{2}-1\right)+1\right)^{2}} D(h)=π((nh)2(α21)+1)2α2
其中:
α = r o u g h n e s s 2 \alpha = roughness^2 α=roughness2

1.2.3 几何遮挡函数 G

G是几何函数,为了表示微平面的自遮挡从而引起的光线损失,如下图所示:
在这里插入图片描述
左边一幅图中是入射光线无法照射到一些微平面,这种情况称为Shadowing,右边图中是反射光线无法正常到达人眼,称为Masking,而几何函数G正是为了模拟出这两种情况所导致的光线损失,在UE4中采用了Schlick-GGX来进行建模:
G 1 ( v ) = n ⋅ v ( n ⋅ v ) ( 1 − k ) + k G ( l , v ) = G 1 ( l ) G 1 ( v ) G_{1}(\mathbf{v})=\frac{\mathbf{n} \cdot \mathbf{v}}{(\mathbf{n} \cdot \mathbf{v})(1-k)+k} \\ G(\mathbf{l}, \mathbf{v})=G_{1}(\mathbf{l}) G_{1}(\mathbf{v}) G1(v)=(nv)(1k)+knvG(l,v)=G1(l)G1(v)
其中:
k = α 2 α = r o u g h n e s s 2 k=\frac{\alpha}{2} \\ \alpha = roughness^2 k=2αα=roughness2
(注:这里仅仅使用IBL作为光源)

2 基于图像的照明 IBL

不如想象这样一个场景:所有需要渲染的模型都处于一个巨大的球体的中心,球体上的每一个点都会发出光线照射模型,因为球体的相对"巨大",所以模型之上的相对移动都可以忽略,因此对于模型上的每一点能接收到来自球体的光线都由其法线所在半球决定,如下图所示:
在这里插入图片描述

对于一个如下图这样的天空盒只需要给定采样方向就可以获得入射光的辐射度:
(天空盒与球体是互通的)
在这里插入图片描述
采样结果: L i ( p , ω i ) = cubeSampling ⁡ ( ω i ) L_{i}\left(p, \omega_{i}\right)= \operatorname{cubeSampling}\left(\omega_{i}\right) Li(p,ωi)=cubeSampling(ωi)

以上正是基于图像的照明的想法,正如开篇所讲其实就是利用了整个天空盒贴图来当作光源,以更多的环境光源来提升渲染的质量,这里的难点就是,如果我们每算一个点都要去用该点法线所在半球的所有方向来采样天空盒,获得辐射度结果,来充当反射方程的入射光 L i L_i Li,其计算代价依然是巨大的,因此会利用近似和一些预计算的方法来将部分计算结果存储为一张贴图,在真正渲染的时候,通过贴图的采样来辅助计算加快速度。接下来我们将反射方程分解成漫反射部分和镜面反射部分来进行讨论。

2.1 漫反射部分

将第一章提到的Cook-Torrance BRDF 带入反射方程得到:
L o ( p , ω o ) = ∫ Ω + ( k d f l a m b e r t + f s ) L i ( p , ω i ) ( n ⋅ ω i ) d ω i L_{o}\left(p, \omega_{o}\right)=\int_{\Omega^{+}}(k_{d} f_{lambert}+ f_{s}) L_{i}\left(p, \omega_{i}\right) \left(n \cdot \omega_{i}\right) \mathrm{d} \omega_{i} Lo(p,ωo)=Ω+(kdflambert+fs)Li(p,ωi)(nωi)dωi
进一步,将反射方程展开:
L o ( p , ω o ) = ∫ Ω + k d f l a m b e r t L i ( ω i ) n ⋅ ω i d ω i + ∫ Ω + f s L i ( ω i ) n ⋅ ω i d ω i L_{o}\left(p, \omega_{o}\right)=\int_{\Omega^{+}} k_{d} f_{lambert} L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i}+\int_{\Omega^{+}} f_{s} L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i} Lo(p,ωo)=Ω+kdflambertLi(ωi)nωidωi+Ω+fsLi(ωi)nωidωi
其中左半部分即为漫反射部分,右半部分即为镜面反射部分,首先考虑漫反射部分,同时将 f l a m b e r t = ρ π f_{lambert} =\frac{\rho}{\pi} flambert=πρ带入:
L d ( ω o ) = ρ π ∫ Ω + k d L i ( ω i ) n ⋅ ω i d ω i L_{d}\left(\omega_{o}\right)=\frac{\rho}{\pi} \int_{\Omega^+} k_{d} L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i} Ld(ωo)=πρΩ+kdLi(ωi)nωidωi
其中 k d = ( 1 − k s ) ∗ ( 1 − m a t a l n e s s ) k_{d} =(1 - k_s)*(1-matalness) kd=(1ks)(1matalness),而 k s = F ( h , v ) k_s = F(h,v) ks=F(h,v),其中微平面法向 h = ( ω i + ω o ) / ∣ ∣ ω i + ω o ∣ ∣ h=(\omega_i+\omega_o)/||\omega_i+\omega_o|| h=(ωi+ωo)/ωi+ωo,包含积分项,所以 k d k_d kd不能直接提出积分,这里为了简化将其做了一步近似,将 k s k_s ks改为:
k s = F 0 + ( m a x { 1 − r o u g h n e s s , F 0 } − F 0 ) ( 1 − ( n ⋅ ω o ) ) 5 k_s = F_{0}+\left(max\{1-roughness,F_0\}-F_{0}\right)(1-(n \cdot \omega_o))^{5} ks=F0+(max{1roughness,F0}F0)(1(nωo))5
与原始式子相比有两个区别:
1.第一个括号的 ( 1 − F 0 ) (1-F_0) (1F0)替换为了 ( m a x { 1 − r o u g h n e s s , F 0 } − F 0 ) (max\{1-roughness,F_0\}-F_{0}) (max{1roughness,F0}F0)
2.第二个括号的 h ⋅ v h\cdot v hv替换为了 n ⋅ ω o n \cdot \omega_o nωo
因此此时 k d k_d kd也与积分项无关,提出得到:
L d ( ω o ) ≈ k d ρ π ∫ Ω L i ( ω i ) n ⋅ ω i d ω i L_{d}\left(\omega_{o}\right)\approx k_{d} \frac{\rho}{\pi} \int_{\Omega} L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i} Ld(ωo)kdπρΩLi(ωi)nωidωi
现在漫反射项的积分值仅仅取决于法线向量 n n n,因为正如本章一开始的火柴人示意图所示, n n n所在半球会决定所有的 ω i \omega_i ωi方向。

对于积分的计算可以直接使用蒙特卡洛积分的方法,在 n n n所在的半球上均匀采样来算出无偏的积分近似解(这里把 1 / π 1/\pi 1/π也丢了进去):
1 π ∫ Ω L i ( p , ω i ) n ⋅ ω i d ω i = 1 π ∫ 0 2 π ∫ 0 π 2 L i ( ω i ) cos ⁡ θ sin ⁡ θ d θ d ϕ ≈ 1 π 1 N 1 N 2 ∑ i N 1 ∑ j N 2 L i ( ϕ j , θ i ) cos ⁡ ( θ i ) sin ⁡ ( θ i ) p d f ( θ ) p d f ( ϕ ) \begin{aligned} \frac{1}{\pi} \int_{\Omega} L_{i}\left(p, \omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i} &=\frac{1}{\pi} \int_{0}^{2 \pi} \int_{0}^{\frac{\pi}{2}} L_{i}\left(\omega_{i}\right) \cos \theta \sin \theta \mathrm{d} \theta \mathrm{d} \phi \\ & \approx \frac{1}{\pi} \frac{1}{N_{1} N_{2}} \sum_{i}^{N_{1}} \sum_{j}^{N_{2}} \frac{L_{i}\left( \phi_{j}, \theta_{i}\right) \cos \left(\theta_{i}\right) \sin \left(\theta_{i}\right)}{pdf(\theta)pdf(\phi)} \\ \end{aligned} π1ΩLi(p,ωi)nωidωi=π102π02πLi(ωi)cosθsinθdθdϕπ1N1N21iN1jN2pdf(θ)pdf(ϕ)Li(ϕj,θi)cos(θi)sin(θi)
p d f ( θ ) = 1 0.5 π , p d f ( ϕ ) = 1 2 π pdf(\theta) = \frac{1}{0.5\pi},pdf(\phi) = \frac{1}{2 \pi } pdf(θ)=0.5π1,pdf(ϕ)=2π1带入化简最终得到
1 π ∫ Ω L i ( p , ω i ) n ⋅ ω i d ω i = π 1 N 1 N 2 ∑ i N 1 ∑ j N 2 L i ( ϕ j , θ i ) cos ⁡ ( θ i ) sin ⁡ ( θ i ) \frac{1}{\pi} \int_{\Omega} L_{i}\left(p, \omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i} =\pi \frac{1}{N_{1} N_{2}} \sum_{i}^{N_{1}} \sum_{j}^{N_{2}} L_{i}\left(\phi_{j}, \theta_{i}\right) \cos \left(\theta_{i}\right) \sin \left(\theta_{i}\right) π1ΩLi(p,ωi)nωidωi=πN1N21iN1jN2Li(ϕj,θi)cos(θi)sin(θi)
只要遍历所有法线方向,再利用上式计算出每个法线向量所对应的结果,存储在贴图中即可,称该贴图为irradiance map。同样不难想象,因为遍历了所有法线方向,存储下来的贴图依然是一个6张的天空盒贴图:
在这里插入图片描述
当然最终实际渲染的时候,也是利用法线 n n n对irradiance map直接进行采样,再乘上 k d ρ k_d\rho kdρ即可得到完整漫反射项近似结果。
这里附上c++实现以供参考:
generate_irradiance_map

2.2 镜面反射部分

根据反射方程,镜面反射部分如下:
L s ( ω o ) = ∫ Ω + f s ( ω o , ω i ) L i ( ω i ) n ⋅ ω i d ω i L_s(\omega_o)=\int_{\Omega^{+}} f_{s}(\omega_o,\omega_i) L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i} Ls(ωo)=Ω+fs(ωo,ωi)Li(ωi)nωidωi
其中:
f s = F D G 4 ( N ⋅ ω o ) ( N ⋅ ω i ) f_s = \frac{F D G}{4(N \cdot \omega_o)(N \cdot \omega_i)} fs=4(Nωo)(Nωi)FDG
此时的积分值会因为 f s f_s fs的存在,依赖于更多的变量,如法向 n n n, 观察方向 ω o \omega_o ωo,粗糙度,金属度等等,所以对于该积分的预计算要远比漫反射部分来的棘手,这里我们采用虚幻4所提出来的Spilt Sum Aprroximation,分解如下:

∫ Ω + f s ( ω o , ω i ) L i ( ω i ) n ⋅ ω i d ω i ≈ ( ∑ k N L i ( ω i ( k ) ) ( n ⋅ ω i ( k ) ) ∑ k N ( n ⋅ ω i ( k ) ) ) ( 1 N ∑ j N f s ( ω i ( j ) , ω o ) ( n ⋅ ω i ( j ) ) p d f ( ω i ( j ) ) ) \int_{\Omega^{+}} f_{s}(\omega_o,\omega_i) L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i} \approx \left(\frac{\sum_{k}^{N} L_{i}\left(\omega_{i}^{(k)}\right) (n\cdot \omega_i^{(k)})}{\sum_{k}^{N} (n\cdot \omega_i^{(k)})}\right)\left(\frac{1}{N} \sum_{j}^{N} \frac{f_{s}\left(\omega_{i}^{(j)}, \omega_{o}\right)\left(n \cdot \omega_{i}^{(j)}\right)}{pdf\left(\omega_{i}^{(j)}\right)}\right) Ω+fs(ωo,ωi)Li(ωi)nωidωi(kN(nωi(k))kNLi(ωi(k))(nωi(k)))(N1jNpdf(ωi(j))fs(ωi(j),ωo)(nωi(j)))
接下来对这个分解进行分析

2.2.1 prefilter environment map

(以下推导证明,很大程度参考了Upba的文章,我这里再添加了一些细节的推导过程,感谢大佬的文章)
仔细观察近似之后式子的右半部分,不难发现其实是一个蒙特卡洛积分的形式,我们将其还原:
1 N ∑ j N f s ( ω i ( j ) , ω o ) ( n ⋅ ω i ( j ) ) p d f ( ω i ( j ) ) ≈ ∫ Ω + f s ( ω i , ω o ) n ⋅ ω i d ω i \frac{1}{N} \sum_{j}^{N} \frac{f_{s}\left(\omega_{i}^{(j)}, \omega_{o}\right)\left(n \cdot \omega_{i}^{(j)}\right)}{pdf\left(\omega_{i}^{(j)}\right)} \approx \int_{\Omega^{+}} f_{s}\left(\omega_{i}, \omega_{o}\right) n \cdot \omega_{i} d \omega_{i} N1jNpdf(ωi(j))fs(ωi(j),ωo)(nωi(j))Ω+fs(ωi,ωo)nωidωi
如此,不难进一步推导出,对于分解之后左边括号的内容其实是对这样一个式子的近似:
∑ k N L i ( ω i ( k ) ) ( n ⋅ ω i ( k ) ) ∑ k N ( n ⋅ ω i ( k ) ) ≈ ∫ Ω + f s ( ω i , ω o ) L i ( ω i ) n ⋅ ω i d ω i ∫ Ω + f s ( ω i , ω o ) n ⋅ ω i d ω i \frac{\sum_{k}^{N} L_{i}\left(\omega_{i}^{(k)}\right) (n\cdot \omega_i^{(k)})}{\sum_{k}^{N} (n\cdot \omega_i^{(k)})} \approx \frac{\int_{\Omega^{+}} f_{s}\left(\omega_{i}, \omega_{o}\right) L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i}}{\int_{\Omega^{+}} f_{s}\left(\omega_{i}, \omega_{o}\right) n \cdot \omega_{i} d \omega_{i}} kN(nωi(k))kNLi(ωi(k))(nωi(k))Ω+fs(ωi,ωo)nωidωiΩ+fs(ωi,ωo)Li(ωi)nωidωi
以下我们暂且把右边部分放在一旁,首先解释分解的左边部分。利用蒙特卡洛积分的方法,将分子和分母分别展开:
∫ Ω + f s ( ω i , ω o ) L i ( ω i ) n ⋅ ω i d ω i ∫ Ω + f s ( ω i , ω o ) n ⋅ ω i d ω i ≈ 1 N ∑ k N f s ( ω i ( k ) , ω o ) L i ( ω i ( k ) ) ( n ⋅ ω i ( k ) ) p d f ( ω i ( k ) ) 1 N ∑ k N f s ( ω i ( k ) , ω o ) ( n ⋅ ω i ( k ) ) p d f ( ω i ( k ) ) \frac{\int_{\Omega^{+}} f_{s}\left(\omega_{i}, \omega_{o}\right) L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i}}{\int_{\Omega^{+}} f_{s}\left(\omega_{i}, \omega_{o}\right) n \cdot \omega_{i} d \omega_{i}} \approx \frac{\frac{1}{N} \sum_{k}^{N} \frac{f_s(\omega_i^{(k)},\omega_o) L_{i}\left(\omega_{i}^{(k)}\right)\left(n \cdot \omega_{i}^{(k)}\right)}{pdf\left(\omega_{i}^{(k)}\right)}}{\frac{1}{N} \sum_{k}^{N} \frac{f_s(\omega_i^{(k)},\omega_o)\left(n \cdot \omega_{i}^{(k)}\right)}{pdf\left(\omega_{i}^{(k)}\right)}} Ω+fs(ωi,ωo)nωidωiΩ+fs(ωi,ωo)Li(ωi)nωidωiN1kNpdf(ωi(k))fs(ωi(k),ωo)(nωi(k))N1kNpdf(ωi(k))fs(ωi(k),ωo)Li(ωi(k))(nωi(k))
f s ( ω i ( k ) , ω o ) = D ( ω h ( k ) ) F ( ω o , ω h ( k ) ) G ( ω o , ω i ( k ) ) 4 ( ω o ⋅ n ) ( ω i ( k ) ⋅ n ) f_s(\omega_i^{(k)},\omega_o) = \frac{D\left(\omega_{h}^{(k)}\right) F\left(\omega_{o} ,\omega_{h}^{(k)}\right) G\left(\omega_{o}, \omega_{i}^{(k)}\right)}{4(\omega_o \cdot n)(\omega_i^{(k)}\cdot n)} fs(ωi(k),ωo)=4(ωon)(ωi(k)n)D(ωh(k))F(ωo,ωh(k))G(ωo,ωi(k))代入化简可得:
1 N ∑ k N f s ( ω i ( k ) , ω o ) L i ( ω i ( k ) ) ( n ⋅ ω i ( k ) ) p d f ( ω i ( k ) ) 1 N ∑ k N f s ( ω i ( k ) , ω o ) ( n ⋅ ω i ( k ) ) p d f ( ω i ( k ) ) = 1 N ∑ k N D ( ω h ( k ) ) F ( ω o , ω h ( k ) ) G ( ω o , ω i ( k ) ) L i ( ω i ( k ) ) p d f ( ω i ( k ) ) 1 N ∑ k N D ( ω h ( k ) ) F ( ω o ⋅ ω h ( k ) ) G ( ω o , ω i ( k ) ) p d f ( ω i ( k ) ) = 1 N ∑ k N D ( ω h ( k ) ) F ( ω o , ω h ( k ) ) G 1 ( ω i ( k ) ) L i ( ω i ( k ) ) p d f ( ω i ( k ) ) 1 N ∑ k N D ( ω h ( k ) ) F ( ω o ⋅ ω h ( k ) ) G 1 ( ω i ( k ) ) p d f ( ω i ( k ) ) \begin{aligned} \frac{\frac{1}{N} \sum_{k}^{N} \frac{f_s(\omega_i^{(k)},\omega_o) L_{i}\left(\omega_{i}^{(k)}\right)\left(n \cdot \omega_{i}^{(k)}\right)}{pdf\left(\omega_{i}^{(k)}\right)}}{\frac{1}{N} \sum_{k}^{N} \frac{f_s(\omega_i^{(k)},\omega_o)\left(n \cdot \omega_{i}^{(k)}\right)}{pdf\left(\omega_{i}^{(k)}\right)}} &= \frac{\frac{1}{N} \sum_{k}^{N} \frac{D\left(\omega_{h}^{(k)}\right) F\left(\omega_{o} , \omega_{h}^{(k)}\right) G\left(\omega_{o}, \omega_{i}^{(k)}\right) L_{i}\left(\omega_{i}^{(k)}\right)}{pdf\left(\omega_{i}^{(k)}\right)}}{\frac{1}{N} \sum_{k}^{N} \frac{D\left(\omega_{h}^{(k)}\right) F\left(\omega_{o} \cdot \omega_{h}^{(k)}\right) G\left(\omega_{o}, \omega_{i}^{(k)}\right)}{pdf\left(\omega_{i}^{(k)}\right)}}\\ &= \frac{\frac{1}{N} \sum_{k}^{N} \frac{D\left(\omega_{h}^{(k)}\right) F\left(\omega_{o} , \omega_{h}^{(k)}\right) G_1\left(\omega_{i}^{(k)}\right) L_{i}\left(\omega_{i}^{(k)}\right)}{pdf\left(\omega_{i}^{(k)}\right)}}{\frac{1}{N} \sum_{k}^{N} \frac{D\left(\omega_{h}^{(k)}\right) F\left(\omega_{o} \cdot \omega_{h}^{(k)}\right) G_1\left(\omega_{i}^{(k)}\right)}{pdf\left(\omega_{i}^{(k)}\right)}} \end{aligned} N1kNpdf(ωi(k))fs(ωi(k),ωo)(nωi(k))N1kNpdf(ωi(k))fs(ωi(k),ωo)Li(ωi(k))(nωi(k))=N1kNpdf(ωi(k))D(ωh(k))F(ωoωh(k))G(ωo,ωi(k))N1kNpdf(ωi(k))D(ωh(k))F(ωo,ωh(k))G(ωo,ωi(k))Li(ωi(k))=N1kNpdf(ωi(k))D(ωh(k))F(ωoωh(k))G1(ωi(k))N1kNpdf(ωi(k))D(ωh(k))F(ωo,ωh(k))G1(ωi(k))Li(ωi(k))

接下来对概率密度函数 p d f ( ω i ( k ) ) pdf(\omega_i^{(k)}) pdf(ωi(k))进行推导:
首先根据法线分布函数 D D D的定义,有如下式子成立:
∫ H 2 cos ⁡ θ D ( ω h ) d ω h = 1 \int_{\mathcal{H}^{2}} \cos \theta D\left(\boldsymbol{\omega}_{h}\right) \mathrm{d} \boldsymbol{\omega}_{h}=1 H2cosθD(ωh)dωh=1
其中 θ \theta θ为微平面法向 ω h \omega_h ωh与宏观法向 n n n的夹角。从几何角度很容易解释这个等式,即微平面的面积投影至宏观平面上,大小与宏观角度的面积元大小一致。(详细解释可参考我的cook-torrance brdf推导那篇文章)
而我们都知道的一点是,pdf在其整个积分域的积分值为1,所以该积分式中的被积项 cos ⁡ θ D ( ω h ) \cos \theta D\left(\boldsymbol{\omega}_{h}\right) cosθD(ωh) ω h \omega_h ωh的pdf,这与想要求得的 ω i \omega_i ωi的pdf并不一致,所以需要进一步得到 d ω h \mathrm{d} \omega_{h} dωh d ω i \mathrm{d} {\omega}_{i} dωi的关系:
在这里插入图片描述

首先固定入射方向 ω o \omega_o ωo,微分立体角 d ω h d\omega_h dωh是一个很小的范围,那么反推回去,这样一个很小的范围所对应的入射角自然也是一个很小的范围 d ω i d\omega_i dωi,形象的来看,就是转动平面得到所有微观法线在 d ω h d\omega_h dωh范围之内的平面,通过这些微平面,所得到的入射范围。为了寻求二者的关系,以入射方向 ω o \omega_o ωo z z z轴负方向,建立球面坐标系如下:
在这里插入图片描述
根据图中的单位球面坐标系以及标注的角度,不难得出 ω h \omega_h ωh的球面坐标为(1, θ h \theta_h θh ϕ \phi ϕ),则不难计算出微分立体角

d ω h = s i n θ h d θ h d ϕ d\omega_h=sin \theta_{\mathrm{h}} \mathrm{d} \theta_{\mathrm{h}} \mathrm{d} \phi dωh=sinθhdθhdϕ

同时 ω i \omega_i ωi的球面坐标为(1,2 θ h \theta_h θh ϕ \phi ϕ),因为 θ \theta θ角变为两倍,那么对于 ω i \omega_i ωi来说 θ \theta θ角度的微分变化应该也为两倍,因此计算得到

d ω i = s i n 2 θ h ∗ 2 d θ h ∗ d ϕ = 4 s i n θ h c o s θ h d θ h d ϕ d\omega_i=sin2\theta_h *2d\theta_h*d\phi=4sin\theta_hcos\theta_hd\theta_hd\phi dωi=sin2θh2dθhdϕ=4sinθhcosθhdθhdϕ

此时已经知道了 d ω h d\omega_h dωh d ω o d\omega_o dωo,那么

d ω h = d ω i 4 c o s θ h {d\omega_h}= \frac{d\omega_i} {4cos\theta_h} dωh=4cosθhdωi

将其带入 ω h \omega_h ωh的pdf积分式子中得:

∫ H 2 cos ⁡ θ D ( ω h ) d ω i 4 c o s θ h = 1 \int_{\mathcal{H}^{2}} \cos \theta D\left(\boldsymbol{\omega}_{h}\right) \frac{d\omega_i} {4cos\theta_h}=1 H2cosθD(ωh)4cosθhdωi=1
因此,最终得到 p d f ( ω i ) = cos ⁡ θ D ( ω h ) 4 c o s θ h pdf(\omega_i) = \frac{\cos \theta D\left(\boldsymbol{\omega}_{h}\right)}{4cos\theta_h} pdf(ωi)=4cosθhcosθD(ωh),需要注意得是其中 θ \theta θ为微平面法向 ω h \omega_h ωh与宏观法向 n n n的夹角,而 θ h \theta_h θh ω i \omega_i ωi ω o \omega_o ωo得夹角,将其带入最开始的式子中,得到:
1 N ∑ k N D ( ω h ( k ) ) F ( ω o , ω h ( k ) ) G 1 ( ω i ( k ) ) L i ( ω i ( k ) ) p d f ( ω i ( k ) ) 1 N ∑ k N D ( ω h ( k ) ) F ( ω o ⋅ ω h ( k ) ) G 1 ( ω i ( k ) ) p d f ( ω i ( k ) ) = ∑ k N F ( ω o , ω h ( k ) ) G 1 ( ω i ( k ) ) L i ( ω i ( k ) ) ( ω o ⋅ ω h ( k ) ) ω h ( k ) ⋅ n ∑ k N F ( ω o , ω h ( k ) ) G 1 ( ω i ( k ) ) ( ω o ⋅ ω h ( k ) ) ω h ( k ) ⋅ n \frac{\frac{1}{N} \sum_{k}^{N} \frac{D\left(\omega_{h}^{(k)}\right) F\left(\omega_{o} , \omega_{h}^{(k)}\right) G_1\left(\omega_{i}^{(k)}\right) L_{i}\left(\omega_{i}^{(k)}\right)}{pdf\left(\omega_{i}^{(k)}\right)}}{\frac{1}{N} \sum_{k}^{N} \frac{D\left(\omega_{h}^{(k)}\right) F\left(\omega_{o} \cdot \omega_{h}^{(k)}\right) G_1\left(\omega_{i}^{(k)}\right)}{pdf\left(\omega_{i}^{(k)}\right)}} = \frac{\sum_{k}^{N} \frac{F\left(\omega_{o} , \omega_{h}^{(k)}\right) G_{1}\left(\omega_{i}^{(k)}\right) L_{i}\left(\omega_{i}^{(k)}\right)\left(\omega_{o} \cdot \omega_{h}^{(k)}\right)}{\omega_{h}^{(k)} \cdot n}}{\sum_{k}^{N} \frac{F\left(\omega_{o} ,\omega_{h}^{(k)}\right) G_{1}\left(\omega_{i}^{(k)}\right)\left(\omega_{o} \cdot \omega_{h}^{(k)}\right)}{\omega_{h}^{(k)} \cdot n}} N1kNpdf(ωi(k))D(ωh(k))F(ωoωh(k))G1(ωi(k))N1kNpdf(ωi(k))D(ωh(k))F(ωo,ωh(k))G1(ωi(k))Li(ωi(k))=kNωh(k)nF(ωo,ωh(k))G1(ωi(k))(ωoωh(k))kNωh(k)nF(ωo,ωh(k))G1(ωi(k))Li(ωi(k))(ωoωh(k))
出于以下两点考虑,约去分子分母的菲涅尔项的 F F F
1.当物体表面比较光滑时,采样的 ω h \omega_h ωh都十分接近 ω o \omega_o ωo所以 F F F几乎时一个变化不大的定值,故可以约去
2.当物体表面比较粗糙时,最终的radiance计算结果也会比较粗略,加不加 F F F影响不大
经过上述的一系列近似化简过程我们得到:
∫ Ω + f s ( ω i , ω o ) L i ( ω i ) n ⋅ ω i d ω i ∫ Ω + f s ( ω i , ω o ) n ⋅ ω i d ω i ≈ ∑ k N G 1 ( ω i ( k ) ) L i ( ω i ( k ) ) ( ω o ⋅ ω h ( k ) ) ω h ( k ) ⋅ n ∑ k N G 1 ( ω i ( k ) ) ( ω o ⋅ ω h ( k ) ) ω h ( k ) ⋅ n \frac{\int_{\Omega^{+}} f_{s}\left(\omega_{i}, \omega_{o}\right) L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i}}{\int_{\Omega^{+}} f_{s}\left(\omega_{i}, \omega_{o}\right) n \cdot \omega_{i} d \omega_{i}} \approx \frac{\sum_{k}^{N} \frac{ G_{1}\left(\omega_{i}^{(k)}\right) L_{i}\left(\omega_{i}^{(k)}\right)\left(\omega_{o} \cdot \omega_{h}^{(k)}\right)}{\omega_{h}^{(k)} \cdot n}}{\sum_{k}^{N} \frac{ G_{1}\left(\omega_{i}^{(k)}\right)\left(\omega_{o} \cdot \omega_{h}^{(k)}\right)}{\omega_{h}^{(k)} \cdot n}} Ω+fs(ωi,ωo)nωidωiΩ+fs(ωi,ωo)Li(ωi)nωidωikNωh(k)nG1(ωi(k))(ωoωh(k))kNωh(k)nG1(ωi(k))Li(ωi(k))(ωoωh(k))
虚幻4在此之上做了进一步的假设,即令 ω o = n = R \mathbf{\omega_{o}}=\mathbf{n}=\mathbf{R} ωo=n=R,该假设是因为:对于镜面反射的brdf f ( ω i , ω o ) f(\omega_i,\omega_o) f(ωi,ωo),只会在反射方向 R R R的附近有值,如下图中波瓣所示:
在这里插入图片描述
在不同方向入射时(除掠角),波瓣的变化不大,所以会有:
f ( ω o , ω i ( n ) , n ) ≈ f ( R , ω i ( R ) , R ) f\left(\omega_{o}, \omega_{i}(\mathbf{n}), \mathbf{n}\right) \approx f\left(\mathbf{R}, \omega_{i}(\mathbf{R}), \mathbf{R}\right) f(ωo,ωi(n),n)f(R,ωi(R),R)
转变示意图:
在这里插入图片描述
(注意这里的 ω i \omega_i ωi是根据法线分布采样出法线,再根据观察方向反推得到的)
将假设带入原积分式子得:
∫ Ω ( n ) f s ( ω i , ω o ) L i ( ω i ) n ⋅ ω i d ω i ∫ Ω ( n ) f s ( ω i , ω o ) n ⋅ ω i d ω i ≈ ∫ Ω ( R ) f s ( ω i , R ) L i ( ω i ) R ⋅ ω i d ω i ∫ Ω ( R ) f s ( ω i , R ) R ⋅ ω i d ω i ≜ L c ( R ) \frac{\int_{\Omega(\mathbf{n}) }f_{s}\left(\omega_{i}, \omega_{o}\right) L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i}}{\int_{\Omega(\mathbf{n})} f_{s}\left(\omega_{i}, \omega_{o}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i}} \approx \frac{\int_{\Omega(\mathbf{R})} f_{s}\left(\omega_{i}, \mathbf{R}\right) L_{i}\left(\omega_{i}\right) \mathbf{R} \cdot \omega_{i} \mathrm{d} \omega_{i}}{\int_{\Omega(\mathbf{R})} f_{s}\left(\omega_{i}, \mathbf{R}\right) \mathbf{R} \cdot \omega_{i} \mathrm{d} \omega_{i}} \triangleq L_{c}(\mathbf{R}) Ω(n)fs(ωi,ωo)nωidωiΩ(n)fs(ωi,ωo)Li(ωi)nωidωiΩ(R)fs(ωi,R)RωidωiΩ(R)fs(ωi,R)Li(ωi)RωidωiLc(R)
其中:
L c ( R ) ≈ ∑ k N G 1 ( ω i ( k ) ) L i ( ω i ( k ) ) ( R ⋅ ω h ( k ) ) ω h ( k ) ⋅ R ∑ k N G 1 ( ω i ( k ) ) ( R ⋅ ω h ( k ) ) ω h ( k ) ⋅ R = ∑ k N L ( ω i ( k ) ) G 1 ( ω i ( k ) ) ∑ k N G 1 ( ω i ( k ) ) \begin{aligned} L_{c}(\mathbf{R})&\approx \frac{\sum_{k}^{N} \frac{ G_{1}\left(\omega_{i}^{(k)}\right) L_{i}\left(\omega_{i}^{(k)}\right)\left(\mathbf{R} \cdot \omega_{h}^{(k)}\right)}{\omega_{h}^{(k)} \cdot \mathbf{R} }}{\sum_{k}^{N} \frac{ G_{1}\left(\omega_{i}^{(k)}\right)\left(\mathbf{R} \cdot \omega_{h}^{(k)}\right)}{\omega_{h}^{(k)} \cdot \mathbf{R} }}\\ &=\frac{\sum_{k}^{N} L\left(\omega_{i}^{(k)}\right) G_{1}\left(\omega_{i}^{(k)}\right)}{\sum_{k}^{N} G_{1}\left(\omega_{i}^{(k)}\right)} \end{aligned} Lc(R)kNωh(k)RG1(ωi(k))(Rωh(k))kNωh(k)RG1(ωi(k))Li(ωi(k))(Rωh(k))=kNG1(ωi(k))kNL(ωi(k))G1(ωi(k))
呼~!
经过一众的近似化简推导之后,我们终于得到了与虚幻4所给出的分解十分相似的结果,不过害有一点不一样的是,虚幻4中用 n ⋅ ω i n \cdot \omega_i nωi代替了这里的 G 1 ( ω i ) G_1(\omega_i) G1(ωi),但考虑到二者的变化趋势与值域范围都是相似的,这种近似也是可以理解的。
因此最终对于这部分需要预计算的内容就是:
L c ( R ) ≈ ∑ k N L i ( ω i ( k ) ) ( R ⋅ ω i ( k ) ) ∑ k N ( R ⋅ ω i ( k ) ) L_{c}(\mathbf{R}) \approx \frac{\sum_{k}^{N} L_{i}\left(\omega_{i}^{(k)}\right) (\mathbf{R}\cdot \omega_i^{(k)})}{\sum_{k}^{N} (\mathbf{R}\cdot \omega_i^{(k)})} Lc(R)kN(Rωi(k))kNLi(ωi(k))(Rωi(k))
由于假设了 ω o = n = R \mathbf{\omega_{o}}=\mathbf{n}=\mathbf{R} ωo=n=R,此时该式子仅有两个变量 R \mathbf{R} R和粗糙度roughness(不同的粗糙度会导致 ω i \omega_i ωi的采样结果不同),因此只要固定粗糙度,就可以像irradiance map那样计算出一个预计算的天空盒的6张贴图,一般情况下会设定计算0,0.25,0.5,0.75,1.0共计5个粗糙度等级的情况下的cubemap,最终采样的时候可以选粗糙度最近的cubemap进行双线性插值,也可以利用粗糙度进行三线性插值。不同粗糙度的计算结果图如下:
在这里插入图片描述
需要注意的是这里与irradiance map不同的是需要使用反射方向 R \mathbf{R} R来进行cubemap的采样,附上c++实现:
generate_prefilter_map

2.2.2 BRDF LUT

再观察这个分解的式子:

∫ Ω + f s ( ω o , ω i ) L i ( ω i ) n ⋅ ω i d ω i ≈ ( ∑ k N L i ( ω i ( k ) ) ( n ⋅ ω i ( k ) ) ∑ k N ( n ⋅ ω i ( k ) ) ) ( 1 N ∑ j N f s ( ω i ( j ) , ω o ) ( n ⋅ ω i ( j ) ) p d f ( ω i ( j ) ) ) \int_{\Omega^{+}} f_{s}(\omega_o,\omega_i) L_{i}\left(\omega_{i}\right) n \cdot \omega_{i} \mathrm{d} \omega_{i} \approx \left(\frac{\sum_{k}^{N} L_{i}\left(\omega_{i}^{(k)}\right) (n\cdot \omega_i^{(k)})}{\sum_{k}^{N} (n\cdot \omega_i^{(k)})}\right)\left(\frac{1}{N} \sum_{j}^{N} \frac{f_{s}\left(\omega_{i}^{(j)}, \omega_{o}\right)\left(n \cdot \omega_{i}^{(j)}\right)}{pdf\left(\omega_{i}^{(j)}\right)}\right) Ω+fs(ωo,ωi)Li(ωi)nωidωi(kN(nωi(k))kNLi(ωi(k))(nωi(k)))(N1jNpdf(ωi(j))fs(ωi(j),ωo)(nωi(j)))
其中左半部分已经在上一节中给出了详细解释,右半部分本质就是一个蒙特卡洛积分的形式,还原之后形式如下:
1 N ∑ j N f s ( ω i ( j ) , ω o ) ( n ⋅ ω i ( j ) ) p d f ( ω i ( j ) ) ≈ ∫ Ω + f s ( ω i , ω o ) n ⋅ ω i d ω i \frac{1}{N} \sum_{j}^{N} \frac{f_{s}\left(\omega_{i}^{(j)}, \omega_{o}\right)\left(n \cdot \omega_{i}^{(j)}\right)}{pdf\left(\omega_{i}^{(j)}\right)} \approx \int_{\Omega^{+}} f_{s}\left(\omega_{i}, \omega_{o}\right) n \cdot \omega_{i} d \omega_{i} N1jNpdf(ωi(j))fs(ωi(j),ωo)(nωi(j))Ω+fs(ωi,ωo)nωidωi
此时积分中含有的变量为: F 0 , ω o , n F_0,\omega_o,n F0,ωo,n和粗糙度,由于这里考虑的是各向同性的情况,所以针对于 ω o , n \omega_o,n ωo,n只需要用二者之间的夹角 θ \theta θ作为变量即可。但3个变量的存在依然不理想,接下来需要做的就是想办法消去 F 0 F_0 F0使得预计算成为可能。
在这里对它重新进行推导:
∫ Ω + f s ( ω i , ω o ) n ⋅ ω i d ω i = ∫ Ω + f s ( ω i , ω o ) F ( ω o , h ) F ( ω o , h ) n ⋅ ω i d ω i = ∫ Ω + f s ( ω i , ω o ) F ( ω o , h ) ( F 0 + ( 1 − F 0 ) ( 1 − ω o ⋅ h ) 5 ) n ⋅ ω i d ω i = F 0 ∫ Ω + f s ( ω i , ω o ) F ( ω o , h ) ( 1 − ( 1 − ω o ⋅ h ) 5 ) n ⋅ ω i d ω i + ∫ Ω + f s ( ω i , ω o ) F ( ω o , h ) ( 1 − ω o ⋅ h ) 5 n ⋅ ω i d ω i = F 0 ∫ Ω + D ( ω h ) G ( ω o , ω i ) 4 ( ω o ⋅ n ) ( ω i ⋅ n ) ( 1 − ( 1 − ω o ⋅ h ) 5 ) n ⋅ ω i d ω i + ∫ Ω + D ( ω h ) G ( ω o , ω i ) 4 ( ω o ⋅ n ) ( ω i ⋅ n ) ( 1 − ω o ⋅ h ) 5 n ⋅ ω i d ω i = F 0 ∗  A +  B \begin{aligned} \int_{\Omega^{+}} f_{s}\left(\omega_{i}, \omega_{o}\right) n \cdot \omega_{i} d \omega_{i}=& \int_{\Omega^{+}} f_{s}\left(\omega_{i}, \omega_{o}\right) \frac{F\left(\omega_{o}, h\right)}{F\left(\omega_{o}, h\right)} n \cdot \omega_{i} d \omega_{i} \\ =& \int_{\Omega^{+}} \frac{f_{s}\left(\omega_{i}, \omega_{o}\right)}{F\left(\omega_{o}, h\right)}\left(F_{0}+\left(1-F_{0}\right)\left(1-\omega_{o} \cdot h\right)^{5}\right) n \cdot \omega_{i} d \omega_{i} \\ =& F_{0} \int_{\Omega^{+}} \frac{f_{s}\left(\omega_{i}, \omega_{o}\right)}{F\left(\omega_{o}, h\right)}\left(1-\left(1-\omega_{o} \cdot h\right)^{5}\right) n \cdot \omega_{i} d \omega_{i} \\ &+\int_{\Omega^{+}} \frac{f_{s}\left(\omega_{i}, \omega_{o}\right)}{F\left(\omega_{o}, h\right)}\left(1-\omega_{o} \cdot h\right)^{5} n \cdot \omega_{i} d \omega_{i} \\ =& F_{0} \int_{\Omega^{+}} \frac{D(\omega_h)G(\omega_o,\omega_i)}{4(\omega_o \cdot n)(\omega_i \cdot n)}\left(1-\left(1-\omega_{o} \cdot h\right)^{5}\right) n \cdot \omega_{i} d \omega_{i} \\ &+\int_{\Omega^{+}} \frac{D(\omega_h)G(\omega_o,\omega_i)}{4(\omega_o \cdot n)(\omega_i \cdot n)}\left(1-\omega_{o} \cdot h\right)^{5} n \cdot \omega_{i} d \omega_{i} \\ =& F_{0} * \text { A}+\text { B} \end{aligned} Ω+fs(ωi,ωo)nωidωi=====Ω+fs(ωi,ωo)F(ωo,h)F(ωo,h)nωidωiΩ+F(ωo,h)fs(ωi,ωo)(F0+(1F0)(1ωoh)5)nωidωiF0Ω+F(ωo,h)fs(ωi,ωo)(1(1ωoh)5)nωidωi+Ω+F(ωo,h)fs(ωi,ωo)(1ωoh)5nωidωiF0Ω+4(ωon)(ωin)D(ωh)G(ωo,ωi)(1(1ωoh)5)nωidωi+Ω+4(ωon)(ωin)D(ωh)G(ωo,ωi)(1ωoh)5nωidωiF0 A+ B
推导的最后一步已经成功的将积分内的 F 0 F_0 F0给提了出去,所以此时的变量仅有 θ \theta θ和粗糙度,因为其二者范围都在0~1,完全可以用一张二维的贴图存储预计算结果,横轴坐标表示 θ \theta θ,纵轴坐标表示粗糙度,对于贴图的颜色值,其中red通道存放A值,green通道存放B值即可,对于A和B的计算依然是利用蒙特卡洛积分即可:
 A ≈ 1 N ∑ k N D ( ω h ( k ) ) G ( ω o , ω i ( k ) ) 4 ( ω o ⋅ n ) ( ω i ( k ) ⋅ n ) ( 1 − ( 1 − ω o ⋅ ω h ( k ) ) 5 ) ( ω i ( k ) ⋅ n ) p d f ( ω i ( k ) ) \text { A} \approx \frac{1}{N} \sum_{k}^{N} \frac{\frac{D\left(\omega_{h}^{(k)}\right) G\left(\omega_{o}, \omega_{i}^{(k)}\right)}{4\left(\omega_{o} \cdot n\right)\left(\omega_{i}^{(k)} \cdot n\right)}\left(1-\left(1-\omega_{o} \cdot \omega_{h}^{(k)}\right)^{5}\right)\left(\omega_{i}^{(k)} \cdot n\right)}{pdf\left(\omega_{i}^{(k)}\right)}  AN1kNpdf(ωi(k))4(ωon)(ωi(k)n)D(ωh(k))G(ωo,ωi(k))(1(1ωoωh(k))5)(ωi(k)n)
将2.2.1节所推导得到的 p d f ( ω i ) = cos ⁡ θ D ( ω h ) 4 c o s θ h pdf(\omega_i) = \frac{\cos \theta D\left(\boldsymbol{\omega}_{h}\right)}{4cos\theta_h} pdf(ωi)=4cosθhcosθD(ωh)带入化简可得:

 A ≈ 1 N ∑ k N G ( ω o , ω i ( k ) ) ( ω o ⋅ ω h ( k ) ) ( 1 − ( 1 − ω o ⋅ ω h ( k ) ) 5 ) ( ω o ⋅ n ) ( ω h ( k ) ⋅ n ) \text { A} \approx \frac{1}{N} \sum_{k}^{N} \frac{G\left(\omega_{o}, \omega_{i}^{(k)}\right)\left(\omega_{o} \cdot \omega_{h}^{(k)}\right)\left(1-\left(1-\omega_{o} \cdot \omega_{h}^{(k)}\right)^{5}\right)}{\left(\omega_{o} \cdot n\right)\left(\omega_{h}^{(k)} \cdot n\right)}  AN1kN(ωon)(ωh(k)n)G(ωo,ωi(k))(ωoωh(k))(1(1ωoωh(k))5)
同样不难推导出B:
 B ≈ 1 N ∑ k N G ( ω o , ω i ( k ) ) ( ω o ⋅ ω h ( k ) ) ( 1 − ω o ⋅ ω h ( k ) ) 5 ( ω o ⋅ n ) ( ω h ( k ) ⋅ n ) \text { B} \approx \frac{1}{N} \sum_{k}^{N} \frac{G\left(\omega_{o}, \omega_{i}^{(k)}\right)\left(\omega_{o} \cdot \omega_{h}^{(k)}\right)\left(1-\omega_{o} \cdot \omega_{h}^{(k)}\right)^{5}}{\left(\omega_{o} \cdot n\right)\left(\omega_{h}^{(k)} \cdot n\right)}  BN1kN(ωon)(ωh(k)n)G(ωo,ωi(k))(ωoωh(k))(1ωoωh(k))5

计算得到的贴图称为LUT,如下:
在这里插入图片描述
附上lut计算代码:
IntegrateBRDF

最后在真正渲染时,计算某个点着色的过程只需要对贴图采样再加以计算即可:
L ( ω o ) = k d ρ IrradianceMap ( n ) + PrefilterMap ( R ) ( F 0 ∗  A  +  B ) L\left(\omega_{o}\right)=k_{d} \rho \text{IrradianceMap}(\mathbf{n})+\text{PrefilterMap}(\mathbf{R})\left(F_{0} * \text { A }+\text { B}\right) L(ωo)=kdρIrradianceMap(n)+PrefilterMap(R)(F0 A + B)
伪代码:

vec3 ibl_fragment_shader()
{
	vec3 f0 = lerp(vec3(0.04), albedo, metalness);
	vec3 F = fresenlschlick_roughness(wo, normal, f0, roughness);
	vec3 kS = F;
	vec3 kD = (1 - metalness) * (vec3(1) - kS);
	
	//diffuse
	vec3 irradiance = cubemap_sample(irradianceMap, normal);
	vec3 diffuse = irradiance * kD * albedo;
	
	//prefilter
	vec3 R = reflect(wo, normal);
	int specular_miplevel = (int)(roughness * max_mip_level + 0.5f);
	vec3 prefilter_color = cubemap_sample(prefilterMap, R, specular_miplevel );
	
	//lut
	vec2 temp= texture_sample(brdfLUT, n_dot_v, roughness);
	float A = temp.x, B = temp.y;
	
	//specular
	vec3 specular = f0 * A + vec3(B, B, B);
	specular = cwise_product(prefilter_color, specular);
	
	vec3 result= kD * diffuse + specular;
	return result;
}

3 总结

以上就是IBL的所有过程了,不难看出为了得到实时的效果,在计算镜面反射项的时候进行了大量的近似,误差主要来源就是这里,但利用IBL对渲染效果提升是巨大的,可以看几张渲染图:
在这里插入图片描述
在这里插入图片描述
最后再贴一下我自己写的软光栅渲染器吧:

SRender
简单的Blinn-Phong模型与IBL都有实现。包括一些其它的图形学基础算法,这里就不在列举了。
主要特点是纯C++实现,没有任何依赖,核心代码大概在2000多行,因此比较适合阅读与学习,如果有任何错误与问题也欢迎指正交流!
在这里插入图片描述

Reference

[1]Ubp.a:深入理解 PBR/基于图像照明 (IBL)
[2]moriya苏蛙可:DX12渲染管线(1) - 基于物理的渲染(PBR)
[3] LearnOpenGL
[4] Real shading in Unreal Engine 4
[5] Background: Physics and Math of Shading by Naty Hoffmann

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值