Physically Based Rendering From Theory To Implementation
翻译:https://pbr-book.org/4ed/Reflection_Models/Rough_Dielectric_BSDF
总目录: Physically Based Rendering From Theory To Implementation - 基于物理的渲染从理论到实践第四版原书翻译
文章目录
9.7 Rough Dielectric BSDF 粗糙介电质BSDF
现在我们将把9.6节的微面方法扩展到粗糙介质的情况。这涉及到两个值得注意的变化:由于电介质的特点是反射和折射,模型必须意识到这两个独立的组成部分。在折射的情况下,斯涅尔定律将进一步取代计算中决定入射方向的反射定律。
图9.32是用Torrance-Sparrow模型渲染的龙,包括反射和透射。
图9.32:用Torrance-Sparrow microfacet模型渲染的龙模型,同时具有反射(a)和透射(b)。(模型由Christian schller提供)
和前面一样,我们将从描述生成样本的概率密度开始。然后,隐含的BSDF直接从这个密度和由散射相互作用封装的事件序列中得出:可见的正常采样,反射或折射,以及菲涅耳和掩蔽项的衰减。
粗糙介电质 PDF
密度的计算出现在下面的片段中,我们先前在讨论光滑介质情况下省略了它。
// bxdfs.cpp DielectricBxDF::PDF
<<Evaluate sampling PDF of rough dielectric BSDF>>=
<<Compute generalized half vector wm>>
<<Discard backfacing microfacets>>
<<Determine Fresnel reflectance of rough dielectric boundary>>
<<Compute probabilities pr and pt for sampling reflection and transmission>>
<<Return PDF for rough dielectric>>
现在我们转向泛化半方向矢量,讨论它需要更仔细地看看Snell定律(公式(9.2)),它与折射界面入射方向和出射方向的仰角和方位角有关:
η o s i n θ o = η i s i n θ i a n d ϕ o = ϕ i + π \eta_o sin\theta_o = \eta_isin\theta_i \quad and \quad \phi_o = \phi_i + \pi ηosinθo=ηisinθiandϕo=ϕi+π
由于折射发生在微观几何的水平上,所有这些角度都要在与微面法线 ω m \omega_m ωm对齐的坐标框架内理解。回想一下,第一个方程中的sin指的是垂直于 ω m \omega_m ωm的 ω i \omega_i ωi和 ω o \omega_o ωo的切分量长度。
一个泛化的半方向矢量建立在这个观察的基础上,通过缩放和添加这些方向来抵消切向分量,从而在归一化后产生负责特定折射的表面法线。它被定义为
ω
m
=
η
i
ω
i
+
η
o
ω
o
∥
η
i
ω
i
+
η
o
ω
o
∥
=
η
ω
i
+
ω
o
∥
η
ω
i
+
ω
o
∥
\omega_{\mathrm{m}}=\frac{\eta_{\mathrm{i}} \omega_{\mathrm{i}}+\eta_{\mathrm{o}} \omega_{\mathrm{o}}}{\left\|\eta_{\mathrm{i}} \omega_{\mathrm{i}}+\eta_{\mathrm{o}} \omega_{\mathrm{o}}\right\|}=\frac{\eta \omega_{\mathrm{i}}+\omega_{\mathrm{o}}}{\left\|\eta \omega_{\mathrm{i}}+\omega_{\mathrm{o}}\right\|}
ωm=∥ηiωi+ηoωo∥ηiωi+ηoωo=∥ηωi+ωo∥ηωi+ωo
(
9.34
)
(9.34)
(9.34)
其中 η = η i / η o \eta=\eta_i/\eta_o η=ηi/ηo 为采样方向 ω i \omega_i ωi 的相对折射率。反射情况被简单地包括在内,因为 η i = η o \eta_i=\eta_o ηi=ηo没有折射发生。下一个片段实现了这种计算,包括处理无效配置(例如,完全掠射发生率),其中BSDF及其采样密度的值都为零。
<<Compute generalized half vector wm>>=
Float cosTheta_o = CosTheta(wo), cosTheta_i = CosTheta(wi);
bool reflect = cosTheta_i * cosTheta_o > 0;
float etap = 1;
if (!reflect)
etap = cosTheta_o > 0 ? eta : (1 / eta);
Vector3f wm = wi * etap + wo;
if (cosTheta_i == 0 || cosTheta_o == 0 || LengthSquared(wm) == 0) return {};
wm = FaceForward(Normalize(wm), Normal3f(0, 0, 1));
最后一行反映了一个重要的实现细节:在前面的公式(9.34)中的定义中, ω m \omega_m ωm总是指向更密集的介质,而pbrt使用的约定是微观和宏观法线面向一致(即, ω m ⋅ n > 0 \omega_m \cdot n >0 ωm⋅n>0)。因此,在实际操作中,我们计算如下修改后的半方向矢量,其中 n = ( 0 , 0 , 1 ) n = (0,0,1) n=(0,0,1)在局部坐标中:
( 9.35 ) 公式丢失 (9.35)公式丢失 (9.35)公式丢失
其次,相对于入射或出射方向背面的微面没有贡献,必须丢弃。
<<Discard backfacing microfacets>>=
// 丢弃背面的微面
if (Dot(wm, wi) * cosTheta_i < 0 || Dot(wm, wo) * cosTheta_o < 0)
return {};
给定 ω m \omega_m ωm,我们可以利用菲涅耳方程的专门介电项来计算菲涅耳反射和折射项。
<<Determine Fresnel reflectance of rough dielectric boundary>>=
// 测定粗糙介质边界的菲涅耳反射率
Float R = FrDielectric(Dot(wo, wm), eta);
Float T = 1 - R;
我们现在有了计算对于 ω i \omega_i ωi的PDF所需的值,这取决于它是在表面反射还是折射。
<<Return PDF for rough dielectric>>=
Float pdf;
if (reflect) {
<<Compute PDF of rough dielectric reflection>>
} else {
<<Compute PDF of rough dielectric transmission>>
}
return pdf;
如前所述, ω m \omega_m ωm和 ω i \omega_i ωi之间的双射映射提供了变量的变化,其雅可比行列式至关重要,因此我们可以正确地推断采样方向 ω i \omega_i ωi的概率密度。在折射情况下,推导更复杂;请参阅“进一步阅读”部分,以获取其派生的指针。最终行列式由下式给出:
d ω m = η i 2 ∣ ω i ⋅ ω m ∣ ( η i ( ω i ⋅ ω m ) + η o ( ω o ⋅ ω m ) ) 2 d ω i = ∣ ω o ⋅ ω m ∣ ( ( ω i ⋅ ω m ) + ( ω o ⋅ ω m ) / η ) 2 d ω i . \begin{aligned} \mathrm{d} \omega_{\mathrm{m}} & =\frac{\eta_{\mathrm{i}}^{2}\left|\omega_{\mathrm{i}} \cdot \omega_{\mathrm{m}}\right|}{\left(\eta_{\mathrm{i}}\left(\omega_{\mathrm{i}} \cdot \omega_{\mathrm{m}}\right)+\eta_{\mathrm{o}}\left(\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right)\right)^{2}} \mathrm{~d} \omega_{\mathrm{i}} \\ & =\frac{\left|\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right|}{\left(\left(\omega_{\mathrm{i}} \cdot \omega_{\mathrm{m}}\right)+\left(\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right) / \eta\right)^{2}} \mathrm{~d} \omega_{\mathrm{i}} . \end{aligned} dωm=(ηi(ωi⋅ωm)+ηo(ωo⋅ωm))2ηi2∣ωi⋅ωm∣ dωi=((ωi⋅ωm)+(ωo⋅ωm)/η)2∣ωo⋅ωm∣ dωi.
( 9.36 ) (9.36) (9.36)
再一次,这种关系使得我们可以评估通过可见光法向采样和散射相结合得到的采样入射方向 ω i \omega_i ωi的单位立体角概率:
p ( ω i ) = D ω 0 ( ω m ) d ω m d ω i = D ω o ( ω m ) ∣ ω o ⋅ ω m ∣ ( ( ω i ⋅ ω m ) + ( ω o ⋅ ω m ) / η ) 2 p\left(\omega_{\mathrm{i}}\right)=D_{\omega_{0}}\left(\omega_{\mathrm{m}}\right) \frac{\mathrm{d} \omega_{\mathrm{m}}}{\mathrm{d} \omega_{\mathrm{i}}}=\frac{D_{\omega_{\mathrm{o}}}\left(\omega_{\mathrm{m}}\right)\left|\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right|}{\left(\left(\omega_{\mathrm{i}} \cdot \omega_{\mathrm{m}}\right)+\left(\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right) / \eta\right)^{2}} p(ωi)=Dω0(ωm)dωidωm=((ωi⋅ωm)+(ωo⋅ωm)/η)2Dωo(ωm)∣ωo⋅ωm∣
( 9.37 ) (9.37) (9.37)
下面的代码片段实现了这个计算,同时还考虑了采样传输组件的离散概率 p t / ( p r + p t ) pt / (pr + pt) pt/(pr+pt)。
<<Compute PDF of rough dielectric transmission>>=
// 计算粗糙介质折射的PDF
Float denom = Sqr(Dot(wi, wm) + Dot(wo, wm) / etap);
Float dwm_dwi = AbsDot(wi, wm) / denom;
pdf = mfDistrib.PDF(wo, wm) * dwm_dwi * pt / (pr + pt);
最后,反射分量的密度与用于导体的模型一致,除了对于选择反射分量的额外离散概率 p r / ( p r + p t ) pr / (pr + pt) pr/(pr+pt)。
<<Compute PDF of rough dielectric reflection>>=
pdf = mfDistrib.PDF(wo, wm) / (4 * AbsDot(wo, wm)) * pr / (pr + pt);
粗糙介电质 BSDF
BSDF求值类似地分为反射和透射成分。
<<Evaluate rough dielectric BSDF>>=
<<Compute generalized half vector wm>>
<<Discard backfacing microfacets>>
Float F = FrDielectric(Dot(wo, wm), eta);
if (reflect) {
<<Compute reflection at rough dielectric interface>>
} else {
<<Compute transmission at rough dielectric interface>>
}
反射分量遵循片段<<Evaluate rough conductor BRDF>>
中用于导体的方法:
<<Compute reflection at rough dielectric interface>>=
return SampledSpectrum(mfDistrib.D(wm) * mfDistrib.G(wo, wi) * F /
std::abs(4 * cosTheta_i * cosTheta_o));
对于透射分量,我们可以再次推导出有效散射分布,方法是将渲染方程的单样本蒙特卡罗估计等于菲涅耳折射、遮蔽和入射辐射的乘积。
f t ( p , ω o , ω i ) L i ( p , ω i ) ∣ cos θ i ∣ p ( ω i ) = ! ( 1 − F ( ω o ⋅ ω m ) ) G 1 ( ω i ) L i ( p , ω i ) . \frac{f_{\mathrm{t}}\left(\mathrm{p}, \omega_{\mathrm{o}}, \omega_{\mathrm{i}}\right) L_{\mathrm{i}}\left(\mathrm{p}, \omega_{\mathrm{i}}\right)\left|\cos \theta_{\mathrm{i}}\right|}{p\left(\omega_{\mathrm{i}}\right)} \stackrel{!}{=}\left(1-F\left(\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right)\right) G_{1}\left(\omega_{\mathrm{i}}\right) L_{\mathrm{i}}\left(\mathrm{p}, \omega_{\mathrm{i}}\right) . p(ωi)ft(p,ωo,ωi)Li(p,ωi)∣cosθi∣=!(1−F(ωo⋅ωm))G1(ωi)Li(p,ωi).
( 9.38 ) (9.38) (9.38)
将式(9.37)中的PDF代入,求解BTDF f t ( p , ω o , ω i ) f_t(p,\omega_o,\omega_i) ft(p,ωo,ωi)得到
f t ( p , ω o , ω i ) = D ω o ( ω m ) ∣ ω o ⋅ ω m ∣ D ω o ( ω m ) ( 1 − F ( ω o ⋅ ω m ) ) G 1 ( ω i ) ( ( ω i ⋅ ω m ) + ( ω o ⋅ ω m ) / η ) 2 ∣ cos θ i ∣ f_{\mathrm{t}}\left(\mathrm{p}, \omega_{\mathrm{o}}, \omega_{\mathrm{i}}\right)=\frac{D_{\omega_{\mathrm{o}}}\left(\omega_{\mathrm{m}}\right)\left|\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right| D_{\omega_{\mathrm{o}}}\left(\omega_{\mathrm{m}}\right)\left(1-F\left(\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right)\right) G_{1}\left(\omega_{\mathrm{i}}\right)}{\left(\left(\omega_{\mathrm{i}} \cdot \omega_{\mathrm{m}}\right)+\left(\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right) / \eta\right)^{2}\left|\cos \theta_{\mathrm{i}}\right|} ft(p,ωo,ωi)=((ωi⋅ωm)+(ωo⋅ωm)/η)2∣cosθi∣Dωo(ωm)∣ωo⋅ωm∣Dωo(ωm)(1−F(ωo⋅ωm))G1(ωi)
( 9.39 ) (9.39) (9.39)
最后,插入式(9.23)中可见正态分布的定义,并切换到更精确的双向遮蔽因子G。
f t ( p , ω 0 , ω i ) = D ( ω m ) ( 1 − F ( ω o ⋅ ω m ) ) G ( ω i , ω o ) ( ( ω i ⋅ ω m ) + ( ω o ⋅ ω m ) / η ) 2 ∣ ω i ⋅ ω m ∣ ∣ ω o ⋅ ω m ∣ ∣ cos θ i ∣ ∣ cos θ o ∣ f_{\mathrm{t}}\left(\mathrm{p}, \omega_{0}, \omega_{\mathrm{i}}\right)=\frac{D\left(\omega_{\mathrm{m}}\right)\left(1-F\left(\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right)\right) G\left(\omega_{\mathrm{i}}, \omega_{\mathrm{o}}\right)}{\left(\left(\omega_{\mathrm{i}} \cdot \omega_{\mathrm{m}}\right)+\left(\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right) / \eta\right)^{2}} \frac{\left|\omega_{\mathrm{i}} \cdot \omega_{\mathrm{m}}\right|\left|\omega_{\mathrm{o}} \cdot \omega_{\mathrm{m}}\right|}{\left|\cos \theta_{\mathrm{i}}\right|\left|\cos \theta_{\mathrm{o}}\right|} ft(p,ω0,ωi)=((ωi⋅ωm)+(ωo⋅ωm)/η)2D(ωm)(1−F(ωo⋅ωm))G(ωi,ωo)∣cosθi∣∣cosθo∣∣ωi⋅ωm∣∣ωo⋅ωm∣
( 9.40 ) (9.40) (9.40)
下一个片段实现了这个表达式。它还结合了先前在完美镜面情况下遇到的非对称散射的方向测试和处理(第9.5.2节)。
<<Compute transmission at rough dielectric interface>>=
Float denom = Sqr(Dot(wi, wm) + Dot(wo, wm)/etap) * cosTheta_i * cosTheta_o;
Float ft = mfDistrib.D(wm) * (1 - F) * mfDistrib.G(wo, wi) *
std::abs(Dot(wi, wm) * Dot(wo, wm) / denom);
<<Account for non-symmetry with transmission to different medium>>
return SampledSpectrum(ft);
粗糙介电质取样
采样通过从可见法线分布中绘制微面法向,计算菲涅耳项,并在反射和透射之间随机选择来进行。
<<Sample rough dielectric BSDF>>=
Vector3f wm = mfDistrib.Sample_wm(wo, u);
Float R = FrDielectric(Dot(wo, wm), eta);
Float T = 1 - R;
<<Compute probabilities pr and pt for sampling reflection and transmission>>
Float pdf;
if (uc < pr / (pr + pt)) {
<<Sample reflection at rough dielectric interface>>
} else {
<<Sample transmission at rough dielectric interface>>
}
再一次,反射分量的处理很简单,除了由于在反射和折射分量之间的离散选择而产生的额外因素外,大多数情况下与导体的情况相匹配。
<<Sample reflection at rough dielectric interface>>=
// 在粗糙介质界面处采样反射
Vector3f wi = Reflect(wo, wm);
if (!SameHemisphere(wo, wi)) return {};
<<Compute PDF of rough dielectric reflection>>
SampledSpectrum f(mfDistrib.D(wm) * mfDistrib.G(wo, wi) * R /
(4 * CosTheta(wi) * CosTheta(wo)));
return BSDFSample(f, wi, pdf, BxDFFlags::GlossyReflection);
折射用例调用Refract()来确定wi。接下来的测试排除了由于浮点数运算的近似性质而很少出现的不一致。例如,Refract()有时可能表示一个完全的内部反射配置,这是不一致的,因为在这种情况下不应该采样折射组件。
<<Sample transmission at rough dielectric interface>>=
Float etap;
Vector3f wi;
bool tir = !Refract(wo, (Normal3f)wm, eta, &etap, &wi);
if (SameHemisphere(wo, wi) || wi.z == 0 || tir)
return {};
<<Compute PDF of rough dielectric transmission>>
<<Evaluate BRDF and return BSDFSample for rough transmission>>
最后一步计算公式(9.40)中的BTDF,并将样本信息打包到BSDFSample中。
<<Evaluate BRDF and return BSDFSample for rough transmission>>=
SampledSpectrum ft(T * mfDistrib.D(wm) * mfDistrib.G(wo, wi) *
std::abs(Dot(wi, wm) * Dot(wo, wm) /
(CosTheta(wi) * CosTheta(wo) * denom)));
<<Account for non-symmetry with transmission to different medium>>
return BSDFSample(ft, wi, pdf, BxDFFlags::GlossyTransmission, etap);