物理材质
基于物理的渲染 Physically Based Rendering,PBR 涉及光源、材质、光传输和相机的整条成像过程。实时渲染中常用“PBR”指材质工作流,强调由反射规律组织参数与着色;名字本身不保证每个近似都严格物理准确。
本篇处理表面反射。微表面模型描述局部粗糙度如何形成镜面反射瓣;Disney Principled 则将多种反射效果整理为美术可控参数。云、皮肤和毛发还涉及体积散射、次表面传输或更复杂的结构,不能单靠一个表面 BRDF 完整描述。实时实现也需要在材质种类、精度、存储与逐像素开销之间选择。
微面反射
微表面模型 Microfacet Model 将宏观表面视为许多不同朝向的小镜面。表面看起来粗糙,来自微面朝向的变化;每个微面自身仍作镜面反射。
入射方向 ωi、出射方向 ωo 都取从表面指向外部的单位向量。能将这两方向连接成镜面反射的微面法线是半程向量 Half Vector:
h=∥ωi+ωo∥ωi+ωo.
其余朝向的微面不会将该束入射光反射到当前观察方向。统计这些合适微面的面积,并考虑界面反射与遮挡,得到常用单次反射模型
fss(ωi,ωo)=4(n⋅ωi)(n⋅ωo)F(ωi⋅h)D(h)G(ωi,ωo).
只在入射、出射均处于宏观表面正面时使用。F 决定合适微面反射多少,D 决定这种朝向的微面有多少,G 扣除被其他微面挡住的路径。下标 ss 表示 Single Scattering:这里暂时只计算一次微面反射后离开表面的路径。
分母来自方向与投影面积的换算。固定入射方向,微面法线附近一小块 dωh 映射为出射方向范围
dωo=4∣ωi⋅h∣dωh.
宏观面积 A 中这类微面面积约为 AD(h)dωh,截获入射功率的投影因子为 ωi⋅h。反射后除以宏观出射投影面积 A(n⋅ωo) 和 dωo,微面余弦与方向 Jacobian 中的对应因子抵消,得到 Lo=LiFGDdωi/[4(n⋅ωo)]。再按 BRDF 定义除以入射投影因子 n⋅ωi,就是上式。
这一推导说明分母不能随意换成经验常数。掠射时分母很小,也意味着必须正确处理可见微面与遮挡。
Fresnel
Fresnel 反射 Fresnel Reflectance 描述光在折射率不同的界面上有多少被反射。正视和斜视同一材质,反射比例不同;这与表面是否有金属色是两个问题。

横轴是相对界面法线的入射角,纵轴是反射比例。空气进入折射率约 1.5 的电介质,正入射反射约 4%;接近 90∘ 的掠射角 Grazing Angle 时,反射趋近一。蓝、绿曲线分别表示 s、p 偏振,红线是非偏振平均;p 偏振在 Brewster 角附近可降到零,不能把所有偏振分量都说成随角度单调增加。
对于无吸收电介质,Snell 定律给出 ηisinθi=ηtsinθt。令 ci=cosθi、ct=cosθt,两种偏振的反射率为
Rs=(ηici+ηtctηici−ηtct)2,Rp=(ηtci+ηictηtci−ηict)2,F=2Rs+Rp.
正入射时 ci=ct=1,得到
F0=(ηi+ηtηi−ηt)2.
从高折射率到低折射率传播还可能出现全反射,不能继续对不存在的实折射角套上述数值。导体需要复折射率描述吸收,正入射常有较高且随波长变化的反射,可用 RGB 反射率近似其颜色。

中心附近接近正视,标出的 F0 较低;边缘接近掠射,环境反射更强。这张图用于解释 Fresnel,不是移除几何遮挡项后的对照实验。
实时常采用 Schlick Approximation:
F(c)=F0+(1−F0)(1−c)5,c=ωi⋅h=ωo⋅h.
微面模型中的角度相对微面法线 h,不是直接使用宏观 n⋅ωi。有色导体可以将 F0 设为 RGB,逐通道计算;这仍是近似,不代替所有精确 Fresnel 行为。
法线分布
法线分布函数 Normal Distribution Function,NDF 统计各个朝向的微面面积。“Normal”指法线,不表示它一定是统计学上的正态分布。

左图是方向截面的分布曲线,中图将方向密度映为圆盘明暗,右图表现复杂微面法线分布的方向形状;后两图不是两个材质球的最终着色。法线集中在宏观法线附近时,只有较窄的反射方向范围有贡献;分布更宽,反射瓣也更宽。
定义 D(m)dωm 为单位宏观面积上,法线位于该方向范围的微面面积。微面向宏观法线投影后的总面积等于宏观面积,因此满足
∫Ω+D(m)(n⋅m)dωm=1.
所以 D 不是在普通立体角下积分为一的方向 PDF。采微面法线时,常见密度为 pm=D(m)(n⋅m),也可以采观察方向上的可见微面分布,以进一步减少无效样本。
粗糙度 Roughness 控制分布宽窄;它改变反射方向,不直接表示吸收比例。美术粗糙度 r 与公式参数 α 也不总相同,常用 α=r2,但纹理输入、预过滤、LUT 与 BRDF 必须采用同一约定。
坡度表示
在宏观法线为 z 轴的局部坐标中,将微面法线改写为两个坡度
sx=−mzmx,sy=−mzmy,sx2+sy2=tan2θm.
Beckmann Distribution 假设这两个坡度具有各向同性高斯密度
ps(sx,sy)=πα21exp[−α2sx2+sy2].
坡度平面面积与球面方向的关系为 dωm=cos3θmdsxdsy。投影面积概率需一致:Dcosθmdωm=psdsxdsy,因此
DBeckmann(m)=πα2cos4θmexp(−tan2θm/α2).
tan2 来自坡度的长度,cos−4 来自球面与投影面积的换算。这解释了它为何不是将普通高斯曲线直接放到法线夹角上。α 越小,坡度越集中,外观接近镜面;严格 α=0 是理想镜面极限,有限密度公式不能直接除以零。
GGX长尾
GGX / Trowbridge–Reitz 使用更重的坡度尾部:
ps(s)=π(α2+∥s∥2)2α2.
经同样的 cos−4 换算,得到
DGGX(m)=πcos4θm(α2+tan2θm)2α2=π[1+(α2−1)(n⋅m)2]2α2.

图中橙色 GGX 曲线在偏离中心较多的位置仍有响应,蓝色 Beckmann 衰减更快。这种长尾 Long Tail 使高光周围保留更宽的反射范围。较尖的中心峰与较长尾部可以同时存在,不能只用一个模糊半径描述两种分布的差异。
Generalized Trowbridge–Reitz,GTR 进一步用指数 γ 控制尾部,可写成
Dγ(μ)=[1+(α2−1)μ2]γCγ,μ=n⋅m.
归一化要求 2π∫01Dγ(μ)μdμ=1。令 u=1+(α2−1)μ2,得到
Cγ=π[(α2)1−γ−1](α2−1)(1−γ),γ=1,C1=πlnα2α2−1.
α=1 时取连续极限 C=1/π。γ=2 得到 GGX,γ=1 具有更长尾部;较大 γ 在合适的宽度匹配后可以呈现接近 Beckmann 的形状。

图中各曲线中心对齐以比较尾部,蓝色 γ=1 延伸最远,绿色 γ=2 次之,红色较快下降。该比较强调形状差异,不应将中心归一化后的曲线当成未经缩放的完整 NDF 能量。
微面遮挡
Shadowing 是微面前方的结构挡住入射光,Masking 是反射到观察者的路径被其他微面挡住。几何项 G 同时描述这两类限制。
掠射时光线沿表面行进,遮挡更常见。若随意令 G=1,微面模型的小投影分母与接近一的 Fresnel 可能使反射异常明亮。只调整 D 或粗糙度不能替代可见性处理。
Smith Model 从微面高度和坡度统计近似可见比例。常用可分离形式为
G2(ωi,ωo)≈G1(ωi)G1(ωo).
各向同性 GGX 的单方向形式可写为
G1(θ)=1+1+α2tan2θ2,
宏观背面方向取零。正视时它接近一,掠射时下降。若使用高度相关形式,记 Λ(θ)=(1+α2tan2θ−1)/2,可取 G2=1/[1+Λi+Λo],与两份 G1 乘积并不相同。D、G 和预计算表应按同一模型配套,不能将所有“Smith G”当成唯一的函数。
白炉测试
将不吸收的反射表面放在各方向相同的单位白色环境中,称为白炉测试 White Furnace Test。若完整模型守恒且互易,粗糙度可以改变光向哪些方向反射,但不应无故丢掉能量;在这个均匀环境下,出射结果应与白环境一致。

上排在有结构的环境中观察粗糙度变化,下排才是均匀白环境测试。下排从左到右逐渐变暗,表明单次微面模型随粗糙度增加损失了更多能量;上排反射变模糊本身不能证明是否守恒。
G 将被挡住的单次路径扣掉,这一步是必要的。但是那些光可能撞到第二个微面,继续反射后逃出;单次模型没有追踪后续路径,于是将它们作为损失处理。真实材质吸收也会减少能量,两种原因需要分开。

右侧较陡的微面结构使一次反射更容易朝其他微面传播,而非直接离开表面。图中的箭头示意方向与相互遮挡;实际多跳路径还需要继续求交与 Fresnel 反射。完整多重散射微面模型可以用随机行走计算,实时逐像素求值通常希望采用更便宜的近似。
缺失能量
先令 Fresnel 为一,排除材质吸收。定义单次模型在均匀单位环境下的方向反照率 Directional Albedo:
E(μo)=∫Ω+fssF=1(ωi,ωo)μidωi,μi=n⋅ωi.
E 表示该观察方向上单次模型保留的响应,1−E 是应由后续微面散射补回的缺失响应。因 BRDF 互易,同一函数也可以理解为固定入射方向的半球反射能量。
各向同性时 E 不随方位角变化,只依赖粗糙度和法线余弦。这里始终用 μ=cosθ,θ 相对法线;若角度从切线量起,才应写成相应正弦。
其投影加权平均是
Eavg=π1∫Ω+E(μ)μdω=2∫01E(μ)μdμ.

图中横轴是 μ,纵轴是粗糙度,说明需要二维表;它是预计算值的可视化,不是物体照片。图未给数值色标,不应仅凭黑白去断言某处的具体 E。Eavg 只随粗糙度变化,另存一维表即可。
补偿反射瓣
Kulla–Conty Energy Compensation 添加一份互易的反射瓣,补回 1−E。选择对入射和出射对称的形状
fms(μi,μo)=π(1−Eavg)[1−E(μi)][1−E(μo)].
为什么使用这个分母?对入射方向积分:
∫Ω+fmsμidωi=π(1−Eavg)1−E(μo)∫Ω+[1−E(μi)]μidωi=π(1−Eavg)1−E(μo)[π−πEavg]=1−E(μo).
因此 fssF=1+fms 在白炉下的响应为一。分子对称还保证交换入射、出射后不变。这里对齐的是缺失能量与互易性,并没有逐条恢复真实多次散射的方向形状。

下排在高粗糙度处恢复了上排缺失的反射,左侧低粗糙度变化较小。补偿并非给所有粗糙表面统一加亮常量,它的幅度随入射方向、出射方向和粗糙度变化。
Eavg 接近一时分母很小,同时缺失分子也接近零,需处理数值极限。镜面或近镜面情形可直接跳过很小的补偿,避免由 LUT 误差放大噪声;随意夹分母而不评估分子,会改变归一化。
彩色补偿
恢复 F<1 后,每次微面反射都会有吸收或透射,不能将所有缺失量都补成白色。用余弦加权平均 Fresnel 近似多次反射中的反射比例:
Favg=2∫01F(μ)μdμ.
采用 Schlick 时,可以积分得到 Favg=F0+(1−F0)/21。对有色反射逐 RGB 通道处理,这是将多跳混合后的反射方向近似为较分散分布。
以平均单次逃逸率 Eavg 估计后续过程,光多留一次就乘 Favg(1−Eavg)。记 k 为第一跳之后额外留在微面内的次数,相关项为
Ck=FavgEavg[Favg(1−Eavg)]k.
补偿针对至少发生一次额外微面反射的路径,因此从 k=1 开始求和,并按无色缺失量 1−Eavg 归一化:
Ccolor=1−Eavg1k=1∑∞Ck=1−Favg(1−Eavg)Favg2Eavg.
最终采用 fss+Ccolorfms。Favg=1 时颜色系数为一,回到无吸收情况;反射率很小时,多跳至少经历两次反射,其贡献按 Favg2 降低,符合这一近似的路径含义。
早期形式从 k=0 起算,分子只有一份 Favg;作者修正版附录明确将额外路径从 k=1 起算并补上缺失量归一化,得到上面的平方形式。Kulla 与 Conty 的修正版讲义

下排粗糙金色材质的反射能量更多,同时仍保留颜色。图来自课程沿用的补偿演示,用于说明有色响应;不能据此认为早期演示图的每个数值都对应上述修正版。修正后的彩色补偿在高粗糙度处会比早期版本更暗,防止将真实吸收也补掉。
实时求值
预计算阶段按所选 NDF、几何项和粗糙度约定积分 E(μ,r),再求 Eavg(r)。运行时只需要两次方向查表、一份平均值,再计算附加瓣。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| // 单次模型及 LUT 必须使用相同 NDF、Smith G 和粗糙度约定。 function compensatedBRDF(wi, wo, material): muI = dot(normal, wi) muO = dot(normal, wo) if muI <= 0 or muO <= 0: return 0 single = evaluateMicrofacet(wi, wo, material) Ei = energyLut(muI, material.roughness) Eo = energyLut(muO, material.roughness) Eavg = averageEnergyLut(material.roughness) if 1 - Eavg < smallThreshold: return single additional = (1 - Ei) * (1 - Eo) / (PI * (1 - Eavg)) Favg = material.F0 + (1 - material.F0) / 21 colorWeight = Favg * Favg * Eavg / (1 - Favg * (1 - Eavg)) return single + colorWeight * additional
|
这些计算在 RGB 通道上进行,LUT 误差、数值阈值和各向异性扩展都需另行评估。该补偿是表面反射的近似,不能直接替代完整的透射、多层或次表面 BSDF。
给单次微面 BRDF 随意加一份漫反射会改变能量预算,无法保证守恒。复合材质并非不能有漫反射与镜面两部分,但需要说明光如何分配到界面反射、内部散射和其他层;Kulla–Conty 的附加瓣专门用于补偿微面多跳损失,与任意新增一层漫反射有不同依据。