读书笔记:OpenPBR 规范(3)
3.2 基础基底
材质结构底部的体材料部分,称为基础基底,由金属和电介质两种半无限板层的统计混合构成:
其中 M = base_metalness(基底金属度),该参数控制表面微面区域中金属材质所占的比例。表面区域通常要么完全是金属,要么完全是非金属电介质,但介于 0 和 1 之间的基底金属度值可用于模拟裸金属区域与电介质区域之间的平滑过渡(例如,模拟金属表面的不透明锈迹或油漆)。来自 Substance Painter 等应用程序的金属度贴图可以连接到此参数。控制金属 BRDF 的参数将在"金属"一节中介绍。

电介质基底假定其表面 BSDF 由粗糙的 GGX 电介质微面模型 [Walter2007] 描述,并且其体介质支持吸收和散射(无论其物理成因是电介质本身固有的分子属性(如水),还是嵌入颗粒或薄片(如油漆中的颜料)的分散体所致)。
然而,我们区分了单独的"半透明"电介质体材料和"不透明"电介质体材料,它们通过统计混合方式组合:
其中 T = transmission_weight(透射权重)。

这反映了美术人员的常见工作流程,他们通常要么建模一个可能带有高光和密集次表面散射的不透明表面(如岩石、塑料、皮肤等),要么建模一个具有有限体积吸收和散射量的半透明材质(如玻璃、液体、有机材料等)。这些用例需要不同的参数化方案来进行有效控制,因此将其拆分为单独的板层更为方便。
"半透明基底"将在"半透明基底"一节中描述,而"不透明基底"则在下文进一步分解为"高光漫反射"和"次表面"。transmission_weight 参数用于在这些模型之间进行选择。请注意,从技术上讲,0 到 1 之间的混合权重会产生物理上不明确的状态(因为此时叠加了具有不同属性的体介质),因此我们通常期望此权重充当一个布尔选择器。
不透明基底假定为一种具有密集次表面体积吸收和散射的电介质,在介质密度趋于无穷大的极限情况下,其 BSDF 趋近于理想化的"高光漫反射"BSDF。在某些情况下,需要混合次表面散射和完全不透明的高光漫反射散射,例如在皮肤渲染中,漫反射分量提供皮肤的 surface 细节(雀斑、瑕疵、妆容等),而次表面分量提供皮下血管和组织的颜色细节。为支持这一点,我们将不透明基底设为高光漫反射模型和次表面模型(分别在第 x 节和第 y 节描述)的统计混合:
其中 S = \(subsurface\_weight\)(次表面权重)。

不透明和半透明电介质基底共享相同的电介质界面BSDF $ f_{\text{dielectric}} $ ,其参数称为"高光(specular)"参数,因为它们控制由基底电介质提供的主高光反射波瓣(涂层则提供次级高光波瓣,参见"涂层"一节):
-
高光波瓣形状由表面的粗糙度属性控制,通过 \(specular\_roughness\)(高光粗糙度)和 \(specular\_roughness\_anisotropy\)(高光粗糙度各向异性)参数化(参见"微面元模型NDF"一节)。
-
\(specular\_ior\)(高光折射率)参数控制电介质的折射率。\(specular\_weight\)(高光权重)参数通过将折射率降至参考值以下,提供了一个方便的、可贴图的线性[0,1]乘数,用于调整法线入射时的电介质反射率。当 \(specular\_weight\)为 0 时,高光反射完全消失,因为此时电介质的折射率与周围介质的折射率相等。为方便起见,我们也允许 \(specular\_weight\) 超过 1,从而通过将折射率提高到参考值以上来增加反射率。下面的公式(26)给出了应用的折射率调制公式。
-
\(specular\_color\)(高光颜色)参数调制 $ f_{\text{dielectric}} $ 的菲涅耳因子,但仅针对来自上方的入射光的初次反射,而假定对从上或从下透射的光(或从下方反射的光)没有影响。如果将其从默认的白色修改,这在技术上是非物理的(因为真实的电介质的菲涅耳因子仅取决于折射率),但在实践中可能很有用,可以人为地为高光着色,而不干扰光传输的其他方面,例如由内部介质散射引起的反射、来自下方的反射,或从上或从下的透射。
通过 \(specular\_weight\) 控制的高光折射率调制公式如下。给定现有的 \(specular\_ior\),计算其与周围介质折射率的比值 \(\eta_{s}\)(应根据"涂层"一节中的公式(60)考虑涂层的存在)。给定此比值,$ f_{\text{dielectric}} $ 在法线入射时的电介质菲涅耳反射因子由下式给出:
然后,通过乘以 $ \xi_{s}={specular_{weight}} $ 来调制此菲涅耳因子(来自上方的初始反射)。由此解出调制后的新折射率比值 $ \eta_{s}^{\prime} $:
在任何入射角余弦 $ \mu $ 下,将调制后的折射率比值 $ \eta_{s}^{\prime} $ 应用于与角度相关的电介质菲涅耳公式 $ F(\mu,\eta_{s}^{\prime}) $,即可产生所需的反射率调制。菲涅耳透射因子以及进出基底电介质的折射也应与折射率比值 $ \eta_{s}^{\prime} $ 保持一致。
为方便起见,我们也允许 $ \xi_{s}={specular_{weight}} $ 超过 1,以便将反射率提高到由 \(specular\_ior\) 设定的水平之上。但请注意,存在一个约束 $ \xi_{s}\leq 1/F_{s} $,因为缩放后的反射系数不能超过 1。因此需要在内部进行钳制以确保 $ \xi_{s}\in[0,1/F_{s}] $。

图3:从左到右改变高光折射率(\(specular\_ior\))的值:1.1、1.3、1.5(默认值)
3.2.1 金属
金属完全不透明,并且由于导体的菲涅耳因子与电介质不同,具有一种特征性的、常见的高光形式。因此,金属基底被表示为一个单独的层,该层包含一个不透明的 GGX 微面元导体 BRDF $ f_{\text{conductor}} $,其 NDF 由 specular_roughness(高光粗糙度)和 specular_roughness_anisotropy(高光粗糙度各向异性)参数化(重用了电介质 BSDF $ f_{\text{dielectric}} $ 所用的相同参数,如"微平面模型"一节所述):
导体菲涅耳反射曲线由法线入射和近掠射入射处的颜色(分别为 base_color(基础色)和 specular_color(高光颜色),并乘以相应的权重因子进行缩放)来参数化。这允许通过直接指定法线入射和掠射入射处的(可贴图的)颜色,来艺术指导性地调整掠射边缘的反射率变化,以模拟真实金属中观察到的反射率下降,或仅用于艺术效果 [Hoffman2019]。请注意,如上文所述,这两个颜色参数也用于非金属(即电介质)的高光和漫反射 BRDF。
如前所述,这种非透射的金属基底根据 base_metalness(基底金属度)参数,与电介质基底进行统计混合:
其中 M = base_metalness。
我们为金属菲涅耳因子 $ F_{\text{metal}}(\mu) $ 规定的具体模型是 [Kutz2021] 提出的 "F82-tint" 模型,该模型扩展了 [Hoffman2019] 先前的工作。该模型基于金属菲涅耳因子的标准 Schlick 近似(其中 $ F_{0} $ 是法线入射处的 RGB 反射率,即 base_weight * base_color,$ \mu $ 是入射角余弦):
为了更好地近似金属的实际菲涅耳曲线,在 F82-tint 模型中,Schlick 近似通过一个修正项进行了增强:
其中 $ \bar{\mu}=1/7 $,而 $ F(\bar{\mu}) $ 是在对应于大约 82°(即大致在轮廓边缘附近)的"掠射边缘"角度余弦处期望的金属反射率,这确保了 $ F_{82}(\bar{\mu})=F(\bar{\mu}) $。这个期望的边缘反射率由用户指定为 Schlick 曲线的一个比例色调,通过 specular_color 控制,即:
我们最终采用的金属菲涅耳项由整体乘以 specular_weight(高光权重)给出,以确保当权重趋近于零时,整个金属波瓣被抑制:
// https://renderwonk.com/publications/wp-generalization-adobe/gen-adobe.pdf
vec3 mx_fresnel_hoffman_schlick(float cosTheta, FresnelData fd)
{
const float COS_THETA_MAX = 1.0 / 7.0;
const float COS_THETA_FACTOR = 1.0 / (COS_THETA_MAX * pow(1.0 - COS_THETA_MAX, 6.0));
float x = clamp(cosTheta, 0.0, 1.0);
vec3 a = mix(fd.F0, fd.F90, pow(1.0 - COS_THETA_MAX, fd.exponent)) * (vec3(1.0) - fd.F82) * COS_THETA_FACTOR;
return mix(fd.F0, fd.F90, pow(1.0 - x, fd.exponent)) - a * x * mx_pow6(1.0 - x);
}
vec3 mx_compute_fresnel(float cosTheta, FresnelData fd)
{
if (fd.airy)
{
return mx_fresnel_airy(cosTheta, fd);
}
else if (fd.model == FRESNEL_MODEL_DIELECTRIC)
{
return vec3(mx_fresnel_dielectric(cosTheta, fd.ior.x));
}
else if (fd.model == FRESNEL_MODEL_CONDUCTOR)
{
return mx_fresnel_conductor(cosTheta, fd.ior, fd.extinction);
}
else
{
return mx_fresnel_hoffman_schlick(cosTheta, fd);
}
}
void mx_generalized_schlick_bsdf(ClosureData closureData, float weight, vec3 color0, vec3 color82, vec3 color90, float exponent, vec2 roughness, float thinfilm_thickness, float thinfilm_ior, vec3 N, vec3 X, int distribution, int scatter_mode, inout BSDF bsdf)
{
if (weight < M_FLOAT_EPS)
{
return;
}
if (closureData.closureType != CLOSURE_TYPE_TRANSMISSION && scatter_mode == 1)
{
return;
}
vec3 V = closureData.V;
vec3 L = closureData.L;
N = mx_forward_facing_normal(N, V);
float NdotV = clamp(dot(N, V), M_FLOAT_EPS, 1.0);
vec3 safeColor0 = max(color0, 0.0);
vec3 safeColor82 = max(color82, 0.0);
vec3 safeColor90 = max(color90, 0.0);
FresnelData fd = mx_init_fresnel_schlick(safeColor0, safeColor82, safeColor90, exponent, thinfilm_thickness, thinfilm_ior);
vec2 safeAlpha = clamp(roughness, M_FLOAT_EPS, 1.0);
float avgAlpha = mx_average_alpha(safeAlpha);
if (closureData.closureType == CLOSURE_TYPE_REFLECTION)
{
X = normalize(X - dot(X, N) * N);
vec3 Y = cross(N, X);
vec3 H = normalize(L + V);
float NdotL = clamp(dot(N, L), M_FLOAT_EPS, 1.0);
float VdotH = clamp(dot(V, H), M_FLOAT_EPS, 1.0);
vec3 Ht = vec3(dot(H, X), dot(H, Y), dot(H, N));
vec3 F = mx_compute_fresnel(VdotH, fd);
float D = mx_ggx_NDF(Ht, safeAlpha);
float G = mx_ggx_smith_G2(NdotL, NdotV, avgAlpha);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp;
float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight);
// Note: NdotL is cancelled out
bsdf.response = D * F * G * comp * closureData.occlusion * weight / (4.0 * NdotV);
}
else if (closureData.closureType == CLOSURE_TYPE_TRANSMISSION)
{
vec3 F = mx_compute_fresnel(NdotV, fd);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp;
float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight);
if (scatter_mode != 0)
{
float avgF0 = dot(safeColor0, vec3(1.0 / 3.0));
fd.ior = vec3(mx_f0_to_ior(avgF0));
bsdf.response = mx_surface_transmission(N, V, X, safeAlpha, distribution, fd, vec3(1.0)) * weight;
}
}
else if (closureData.closureType == CLOSURE_TYPE_INDIRECT)
{
vec3 F = mx_compute_fresnel(NdotV, fd);
vec3 comp = mx_ggx_energy_compensation(NdotV, avgAlpha, F);
vec3 dirAlbedo = mx_ggx_dir_albedo(NdotV, avgAlpha, safeColor0, safeColor90) * comp;
float avgDirAlbedo = dot(dirAlbedo, vec3(1.0 / 3.0));
bsdf.throughput = vec3(1.0 - avgDirAlbedo * weight);
vec3 Li = mx_environment_radiance(N, V, X, safeAlpha, distribution, fd);
bsdf.response = Li * comp * weight;
}
}
这种公式化的一个有用特性是,当 specular_weight 和 specular_color 取默认值时,它会简化为常规的 Schlick 反射率。请注意,边缘反射率不能比标准的 Schlick 项更亮,但这在真实金属中通常是成立的。我们认为这是该参数化的一个优点,因为它使得产生具有过亮边缘的、物理上不真实的金属成为不可能。

图4:仅设置 base_color 参数(左)与正确设置 base_color 和 specular_color 参数(右)所产生的金属效果(base_metalness=1 模式下)对比
3.2.2 高光-漫反射
高光-漫反射板层表示基础电介质(参数化方式如"电介质基底"一节所述),其内嵌了一个具有极高密度散射特性的半无限体材料。该板层的 BRDF 是由电介质界面直接反射提供的"光泽"镜面波瓣,与由嵌入基底散射提供的漫反射波瓣组合而成。例如,这可以模拟光亮、完全不透明表面(如密实塑料、岩石和混凝土)的反射。
我们选择将其具体建模为:在具有漫反射 BRDF 的(折射率匹配的)不透明板层之上,覆盖一层电介质"高光"层。

其中 \(S_{\text{gloss}}\) 是一个薄电介质板层,具有粗糙电介质微面元 BRDF(其参数化方式与"电介质基底"一节相同),并且其内部介质与基础电介质相同,但由于其层厚为无穷小,因此消光系数为零:
由于漫反射基底与光泽层的折射率相匹配,菲涅耳反射仅来自光泽层的上界面。不透明基底板层具有一个漫反射 BRDF 波瓣:
其中 $ f_{\text{diffuse}} $ 基于经典的 Oren-Nayar 模型([Oren1994], [Pharr2023])。该模型是一个基于 V 形空腔的微面元模型,假设每个微面元自身遵循朗伯反射。Oren-Nayar 模型由粗糙度 $ \sigma $ 和一个整体 RGB 比例因子 $ \rho $ 参数化。该粗糙度模拟了在实际的粗糙漫反射材料中观察到的"平坦化"效应(图 5)[Oren1994]。

图5:零粗糙度(σ=0,左)与最大粗糙度(σ=1,右)下,使用 EON BRDF 的漫反射材质效果对比。
遗憾的是,原始模型存在瑕疵且不满足能量守恒(即显得过暗)。因此,我们选择采用由 Fujii [Fujii2012] 引入的一种流行的改进版 Oren-Nayar 模型来定义漫反射 BRDF,并辅以一个简单的解析、互易性能量补偿项:
这种形式的 Oren-Nayar 模型被称为"能量守恒型 Oren-Nayar"或 $ \mathbf{EON} $。Oren-Nayar 项 $ f_{\text{ON}} $ 采用 [Fujii2012] 中给出的形式⁶:
粗糙度参数 $ \sigma\in[0,1] $ 由 base_diffuse_roughness 给出。整体权重 $ w_{\text{d}}=\text{base_weight} $。RGB 参数 $ \rho $ 由指定的 base_color 决定,如下所述。
Oren-Nayar 项的方向反照率 \(E_{\text{ON}}(\omega)=w_{\text{d}}\rho\hat{E}_{\text{ON}}(\omega)\) 及其对应的平均反照率 \(\langle\hat{E}_{\text{ON}}\rangle\) 可以通过解析方法确定⁷。能量补偿项 $ f_{\text{ON}}^{\text{comp}} $ 根据反照率 $ \langle\hat{E}_{\text{ON}}\rangle $ 由下式给出:
其中因子 $ \rho_{\text{ms}} $ 近似地解释了微面表面上的多次散射:
可以验证,当 $ \rho\to 1 $ 时(在 $ w_{\text{d}}=1 $ 的情况下),公式 36 中 BRDF 的总方向反照率 $ E_{\text{diffuse}}(\omega)\to 1 $,因此补偿项确保了白色熔炉测试得以通过。请注意,在零粗糙度 $ (\sigma\to 0) $ 的极限情况下,能量补偿项消失,参数 $ \rho $ 等于 $ f_{\text{diffuse}} $ 的反照率。随着粗糙度增加,由于多次散射,$ f_{\text{diffuse}} $ 的反照率会变得比 $ \rho $ 略暗且饱和度更高,这在物理上是真实的。
从物理上讲,由于高光层内的多次相互反射(散射),观察到的颜色会有额外的变暗和饱和度增加,如"涂层变暗"一节所述。然而,在这种情况下,我们希望通过调整 $ f_{\text{diffuse}} $ 的 $ \rho $ 参数来自动补偿这种效应,以使观察到的颜色与输入颜色 $ \mathbf{C}=\text{base_color} $ 相匹配(其思路类似于"次表面散射"一节中描述的反照率重映射)。为了根据底层基底反照率来定义指定颜色的含义,我们将光泽-漫反射板层(在 $ w_{\text{d}}=1 $ 的情况下)的法线方向反射率 $ \mathbf{E}_{\text{glossy-diffuse}} $ 写成一般形式:
其中 \(\mathbf{E}_{\text{spec}}\) 是从电介质界面反射的所有能量(未经宏观透射部分)的法线方向反射率,而 \(\mathbf{E}_{\text{diffuse}}\) 是剩余能量(即经界面宏观透射、在漫反射介质中多次散射、并再次透射出界面部分)对应的法线方向反射率。
然后,我们定义 $ \mathbf{C}=\text{base_color} $,使得在零 base_diffuse_roughness(即 $ \sigma=0 $)的朗伯情况下,透射入板层的剩余能量对应的反射率 $ \mathbf{E}_{\text{diffuse}} $ 由下式给出:
换句话说,所选颜色 C 参数化了传入电介质层的能量中,随后因朗伯界面反射而重新透射出去的能量比例。因此,由于 $ 0 \leq C \leq 1 $,有 $ E_{\text{glossy-diffuse}} \leq 1 $,能量始终守恒;并且如果 C = 1,则 $ E_{\text{glossy-diffuse}} = 1 $,这保证了白色 C 能通过熔炉测试。根据此定义,C 是在菲涅耳反射可忽略的区域观察到的反射颜色(在均匀照明下从法线方向观察),否则观察到的颜色是 C 与灰色的菲涅耳反射的混合,且该混合保持了总反射能量守恒。
根据上述公式得到所需的漫反射反照率 $ E_{\text{diffuse}} $ 后,原则上可以确定能生成该所需 $ E_{\text{diffuse}} $ 的 Oren-Nayar 模型 $ f_{\text{diffuse}}(\omega_i, \omega_o) $ 的参数 $ \rho $。一个合理且实用的、满足此要求的光泽-漫反射板层 BRDF 近似(尽管是非互易的),可以通过公式 7 的非互易反照率缩放近似获得:
在此近似中,为使公式 41 成立,公式 37 和 38 中 Oren-Nayar 模型的 $ \rho $ 参数必须简单地设为 $ \rho = C $。
如果需要互易形式的公式,经典的 Ashikhmin-Shirley 或 Kelemen 模型([Ashikhmin2000], [Kelemen2001], [Kulla2017], [Kutz2021])形式为:
其中 $ \mathcal{N} $ 是一个归一化因子,以确保公式 41 成立。在零粗糙度(即朗伯)Oren-Nayar 基底的情况下,$ \mathcal{N} $ 可以根据电介质折射率制成查找表([Kutz2021]),并且所需的朗伯基底参数 $ \rho $ 等于 C,这与非互易反照率缩放近似中的情况相同。将其扩展到非朗伯粗糙 Oren-Nayar 基底的更一般情况下,需要在查找表中增加粗糙度维度,并且所需的 Oren-Nayar $ \rho $ 将不再简单地等于 C。我们将模型的具体选择及这些细节留给实现自行决定。

图6:木材被渲染为光泽-漫反射材质,由漫反射波瓣(左)、镜面反射波瓣(中)及二者的归一化总和(右)构成。在镜面高光附近,由于能量守恒,漫反射波瓣会自动减弱。
3.2.3 次表面散射
次表面板层表示一种包含致密散射体积介质的电介质,由于光线在表面下的传播和扩散,出射光线离开表面的位置与入射光线不同,从而产生显著的光渗效果。从物理上讲,与"高光-漫反射"一节和"半透明基底"一节中定义的层类似,这是一个具有表面 BSDF $ f_{\text{dielectric}} $ 和均匀内部介质 $ V_{\text{subsurface}}^{\infty} $ 的电介质基底:
与高光-漫反射板层和半透明基底的情况一样,次表面散射由一个具有 BSDF $ f_{\text{dielectric}} $ 的电介质界面界定,该界面通过"高光(specular)"参数(如"电介质基底"一节所述)生成主镜面反射波瓣。与此相结合的是通过电介质界面透射到底层嵌入的次表面介质中的光线所产生的反射,该光线在介质中散射并最终再次透射出去。在这种情况下,次表面介质 $ V_{\text{subsurface}}^{\infty} $ 被赋予了一种参数化方案,特别便于控制致密次表面散射的体积效果:
-
subsurface_radius * subsurface_radius_scale:每个 RGB 通道的平均自由程(MFP),记为 r,即一束光线在介质中被吸收或散射前传播的平均距离。因此,这控制了介质的表观密度。当平均自由程趋近于零时,介质密度趋于无穷大,并接近不透明漫反射表面的外观。作为一个长度值,subsurface_radius 可以是任何大于或等于零的值。为方便起见,我们设定其软范围(soft range)为 [0, 1],从而涵盖常见情况(如皮肤,其平均自由程低于场景长度单位)。subsurface_radius_scale 控制平均自由程的颜色通道依赖性,因此该颜色在通过次表面体积较薄区域透射的光线中可见。
-
subsurface_color:观察到的 RGB 反射反照率颜色 C,该颜色考虑了所有阶次的多次散射(此参数如何参数化观察到的颜色将在下文详细讨论)。
-
subsurface_scatter_anisotropy:介质的相位函数,由标量各向异性 $ g\in[-1,1] $ 参数化。在实践中,实现时可能希望在内部对各向异性进行钳制,因为当各向异性接近 -1 或 1 的极限时,相位函数会变得不确定且渲染不稳定。
我们现在详细说明这些次表面参数如何共同决定底层的体积参数(每通道的消光系数 $ \mu_{t} $、单次散射反照率 $ \alpha $ 以及标量相位函数各向异性 g)。
消光系数由每个通道的平均自由程的倒数简单给出:$ \mu_{t}=1/r $(在 r→0 的极限情况下可能需要正则化以避免数值问题)。请注意,由于消光系数 $ \mu_{t} $ 与各向异性 g 无关,因此各向异性具有熟悉的物理效应:当 g 为正值时,光线比 g 为负值时能更深入地透射到介质中。
为了根据底层介质定义观察到的 subsurface_color C 的含义,需要将介质的反射与电介质界面的菲涅耳反射分离开来。为了精确说明,我们用 \(\mathbf{E}_{\text{subsurface}}\) 表示法线方向的方向反射率(根据公式 2 的定义)。这可以分解为两个部分:
这里 \(\mathbf{E}_{\text{spec}}\) 是所有从电介质界面反射(未经宏观透射)的能量的法线方向反射率。而多次散射反照率 \(\mathbf{E}_{\text{multi-scatter}}\) 是所有剩余反射能量的法线方向反射率,这部分能量是由于(宏观)透射通过界面,在次表面介质中多次散射,并再次透射出去而产生的。然后,我们定义 subsurface_color C 来参数化(假设物理上正确的光传输和半无限均匀板层几何结构)透过界面并再次透射出去被观察到的能量比例,即:
因此,由于 $ 0 \leq C \leq 1 $,有 $ E_{\text{subsurface}} \leq 1 $,所以能量始终守恒;并且如果 $ C = 1 $,则 $ E_{\text{subsurface}} = 1 $,这保证了白色 subsurface_color 能通过熔炉测试。根据此定义,subsurface_color C 是在菲涅耳反射可忽略的区域观察到的反射颜色(在均匀照明下从法线方向观察),否则观察到的颜色是 C 与灰色的菲涅耳反射的混合,且该混合保持了总反射能量守恒。
根据上述公式得到所需的多次散射反照率 $ E_{\text{multi-scatter}} $ 后,原则上可以确定能生成该所需 $ E_{\text{multi-scatter}} $ 的单次散射反照率 $ \alpha $(假设给定了消光系数 $ \mu_{t} $ 和各向异性 $ g $)。我们不要求必须使用任何特定的 $ \alpha(C) $ 理论公式,但越接近满足公式 46,就越接近真实情况。理想情况下,该公式应考虑介质以及电介质界面的所有属性。文献中已推导出许多此类近似公式。一个著名的近似是由 van de Hulst 提出的([Kulla2017], [d'Eon2021]),该近似假设边界折射率匹配(即 $ E_{\text{spec}} = 0 $,因此 $ E_{\text{multi-scatter}} = C $),其中:
对此进行反演,得到用 subsurface_color C 和各向异性 $ g $ 表示的单通道单次散射反照率 $ \alpha $:
这给出了一种近似的 $ \alpha(C) $ 映射关系,但如前所述,它忽略了电介质边界的存在。其他考虑电介质界面的近似形式在各种资料中有所提及(例如 [d'Eon2021], [Burley2018])。我们还注意到,相关的近似可能取决于对次表面界面所做的具体假设,例如在某些情况下,为了效率和改进的收敛性,渲染器可能通过漫反射波瓣来近似边界 BSDF。在这种情况下,使用为此特定界面 BSDF 设计的 $ \alpha(C) $ 映射会更合适,以满足公式 46。
介质的相位函数各向异性 $ g $ 直接由 subsurface_scatter_anisotropy 参数给出⁸。假定相位函数具有标准的 Henyey-Greenstein 形式。
一旦确定了底层的体积介质属性 $ \mu_{t} $, $ \alpha $ 和 $ g $,实现可以自由选择如何根据其用例计算次表面介质中的光传输,例如通过体积路径追踪进行精确计算([Novak2018], [Pharr2023]),或通过使用例如偶极近似 [Jensen2001] 的双向散射表面反射分布函数(BSSRDF)模型进行近似计算。
请注意,subsurface_radius_scale 的默认值设置为 (1, 0.5, 0.25) 以近似瑞利散射效应。如果我们粗略地将 RGB 各通道对应的波长近似为 $ \lambda/nm \approx 650 $, 550, 450,并假设半径与消光系数成反比缩放,那么由于在瑞利散射中,对于波长为 $ \lambda $ 的光,消光系数按 $ \lambda^{-4} $ 缩放,因此半径的预期相对大小为 $ (1,(550/650){4},(450/650)) \approx (1,0.5,0.25) $,故选择了此默认值。这为次表面提供了比使用灰色半径产生的效果略微更真实的默认外观。

图7:改变次表面散射半径(subsurface_radius)所产生的效果
3.2.4 半透明基底
对于基底介质具有半透明特性(即能透射和折射大量光线)的情况,我们提供了一种与次表面模型不同的、更适用于此类用途的底层介质参数化方案。transmission_weight(透射权重)混合参数用于选择此模型,而非选择高光-漫反射与次表面模型的不透明混合。这是一种更传统的体积参数化方案,用于指定物体内部均匀介质的属性(可包含吸收和散射,也可不包含),适用于对多种材质进行建模,范围从透明或带有吸收着色的玻璃、液体,到具有显著视觉散射效果的半透明材质,如蜂蜜、果汁、浑浊水、乳光玻璃或乳白玻璃。
与"高光-漫反射"一节和"次表面"一节中定义的电介质板层类似,其顶部界面由粗糙的 GGX 微面元 BSDF $ f_{\text{dielectric}} $ 描述,其"高光(specular)"参数在"电介质基底"一节中说明。电介质的整体部分 $ V_{\text{dielectric}}^{\infty} $ 是一种支持吸收和散射的体积介质:
$ V_{\text{dielectric}}^{\infty} $ 的折射率由 specular_ior 指定(与整个电介质基底的情况相同)。
$ V_{\text{dielectric}}^{\infty} $ 的体积属性按如下方式指定。RGB 类型的 transmission_color(透射颜色)T 和标量类型的 transmission_depth(透射深度)$ \lambda $ 参数对是一种常用且便于美术人员使用的组合,用于设置体积介质的消光系数 $ \mu_{t} $。
transmission_depth 是指白光在介质内部传播一段距离后,其颜色根据比尔-朗伯定律恰好变为 transmission_color 时所经过的距离,由此可确定内部介质的消光系数 $ \mu_{t} $,公式如下:
作为一个长度值,transmission_depth 可以是任何大于或等于零的值。为方便起见,我们设定其软范围为 [0, 1],从而涵盖常见情况。然而,当 transmission_depth $ \lambda $ 为零时,假定内部介质不存在 $ (\mu_{t}=0) $,此时将使用 transmission_color 以非物理的方式,以一个常量值对电介质折射的菲涅耳因子进行乘法着色(忽略电介质的能量平衡)。
transmission_scatter(透射散射)参数 S 直接设置介质的散射系数 $ \mu_{s} $(作为 transmission_depth 倒数的倍数):
因此,transmission_scatter 的颜色控制了单次散射光线的观察颜色。(请注意,当 transmission_depth $ \lambda $ 为零时,散射系数将被忽略)。吸收系数 $ \mu_{a} $ 随后通过下式计算得出:
如果 $ \mu_{a} $ 的任何分量是负值,则 $ \mu_{a} $ 将被偏移足够的灰度值以使所有分量变为正值,即(使用明显的符号表示法):
经过此偏移后,最终的消光系数由新的 $ \mu_{a} + \mu_{s} $ 给出。这种公式化方法产生的体积参数能够较好地复现独立指定的透射光和单次散射光的颜色。最后,介质的相位函数各向异性 $ g \in [-1,1] $ 由 transmission_scatter_anisotropy 给出(假定为标准 Henyey-Greenstein 相位函数⁸)。

图8:transmission_scatter_anisotropy参数的效果。从左到右:-0.5(后向散射)、0(各向同性)、0.5(前向散射)。
这种现象被称为光学色散(即折射率随波长变化),当光线穿过水、玻璃和钻石等电介质时,会产生常见的彩虹般颜色。对色散的控制与透射参数归为一组,因为这种效应仅在高度透明的折射介质中才显著。
色散由阿贝数 $ V_{d} $ 进行参数化,该数是短、中、长波长处折射率差值的比率,定义如下:
其中,在现代标准定义中,$ n_{\text{long}}=n_{C} $, $ n_{\text{medium}}=n_{d} $ 和 $ n_{\text{short}}=n_{F} $ 分别是材料在夫琅和费 C 线、d 线和 F 光谱线波长处(对应波长分别为 $ \lambda_{C}=656.3 $ nm, $ \lambda_{d}=587.6 $ nm, $ \lambda_{F}=486.1 $ nm)的折射率。色散量(即颜色的角度分离)大致与阿贝数成反比。
任意波长处的折射率可由柯西经验公式确定:
由此可知,若给定阿贝数 $ V_{d} $ 和折射率 $ n_{d}=n(\lambda_{d}) $,则柯西公式中的系数由下式给出:
我们假定 specular_ior(包括通过 specular_weight 进行的任何调制,如公式 26 所示)定义了 $ n(\lambda_{d}) $。因此,在给定 $ V_{d} $ 的情况下,可以确定任意波长 $ \lambda $ 处的折射率 n。渲染器可以使用这个已知的 $ n(\lambda) $ 函数来模拟色散效果,例如通过随机选择一个波长样本,并根据相应的折射率计算折射光线的方向。
然而,阿贝数本身在使用上并不直观,因为色散效果随着阿贝数的减小而增强(阿贝数为无穷大时无色散)。因此,我们更倾向于使用一种对美术人员更友好的参数化方法,即阿贝数由下式指定:
当 transmission_dispersion_scale 为默认值 0 时,阿贝数为无穷大,对应无色散。当该参数为最大值 1 时,阿贝数达到峰值 $ V_{d}={transmission_dispersion_abbe_number} $,其默认值为 20。
选择默认值 20 是因为,常见真实材料中具有最高色散的材料,其阿贝数大致大于或等于该值(例如,不同种类的玻璃的阿贝数在 20 到 91 之间 [Schott2023],水和钻石的阿贝数均在 55 到 56 之间,而由二氧化钛构成的氧化物矿物金红石则表现出极高的色散,其阿贝数为 9.87 [Polyanskiy2023])。在大多数情况下,transmission_dispersion_scale 因此可以作为一个方便的、大致线性的滑块,用于从低色散调整到高色散。对于那些需要特定材料阿贝数的特殊情况,可以通过 transmission_dispersion_abbe_number 来更改阿贝数本身。

Figure 9: 将玻璃的透射色散尺度从0增加到1


浙公网安备 33010602011771号