Banner

「PBR 系列」第二篇 · Disney Principled BRDF 全解析:从十一参数到 BSDF 扩展

核心结论:Disney Principled BRDF 的革命性不在数学——大多数公式在 2012 年前已存在——而在于它第一次为 PBR 定义了一套面向美术的参数体系。BaseColor、Metallic、Roughness、Anisotropic、Sheen、Clearcoat、Subsurface 等 11 个参数后来成为整个游戏行业的资产标准。本篇逐参数拆解,并梳理 2015 年 BSDF 扩展。

一、Disney 2012 的工业意义

Brent Burley 在 SIGGRAPH 2012 课程 “Physically Based Shading at Disney” 中提出的 Disney Principled BRDF,是 PBR 工业化的真正起点。在它之前,PBR 是研究领域的概念;在它之后,PBR 成为游戏与影视生产的事实标准。

它的革命性不在数学上——GGX、Smith、Schlick 在它之前都已成熟——而在于建立了一套面向美术的参数化原则。Burley 在论文里明确写下三条设计哲学:

  1. **使用直观的参数(Intuitive parameters)**而非物理量;
  2. 参数应尽可能少(少即是多);
  3. 参数应被归一化到 [0, 1],并具有合理的中间值;
  4. 参数应能在合理范围内自由组合而不出现明显瑕疵;
  5. 所有美术控制都应参考真实测量数据(MERL 100 数据库)。

这套理念直接催生了现代 PBR 资产工作流(Substance、Quixel、Marmoset),成为跨引擎的事实标准。

参考论文:


二、十一参数完整解析

Disney BRDF 暴露给美术的核心参数:

参数 范围 含义
baseColor RGB ∈ [0,1] 基础反射率:电介质漫反射 / 金属
metallic [0,1] 金属度(0 = 电介质,1 = 金属)
roughness [0,1] 粗糙度(0 = 完全光滑,1 = 完全粗糙)
specular [0,1] 电介质 强度调整(默认 0.5 对应 IOR ≈ 1.5)
specularTint [0,1] 电介质 specular 是否染色到 baseColor
anisotropic [0,1] 各向异性强度(0 = 各向同性)
sheen [0,1] 边缘泛光强度(用于布料)
sheenTint [0,1] sheen 颜色是否倾向 baseColor
clearcoat [0,1] 清漆层强度
clearcoatGloss [0,1] 清漆层光泽度(0 = 缎面、1 = 镜面)
subsurface [0,1] 次表面散射近似强度

注意 Disney 的设计:所有 Specular Tint / Sheen Tint / 各向异性方向 等”颜色或方向类辅助参数”都依附于一个主参数,避免参数膨胀。


三、Disney Diffuse 项

3.1 公式与推导

Disney 的 Burley 在 2012 年提出了一个折中方案:保留 Lambert 的简洁性,同时通过经验拟合引入边缘亮起(grazing retro-reflection)和粗糙度耦合。

原始形式:

其中:

是半向量与视线(或光线)的夹角。

直觉解读:

  • (光线掠射)或 (视线掠射)时, 接近 1;
  • 此时 (高粗糙度),漫反射被增强 → 出现 retro-reflection 效果;
  • 当粗糙度为 0 时,,漫反射被衰减 → 模拟光滑表面 diffuse 减少(更多能量去 specular)。

3.2 整理形式(Lambert + 逆反射)

将原始公式展开后可以等价改写为:

其中

这种整理形式的好处:清楚分离出”理想 Lambert + 逆反射修正”两部分,方便针对性调试与各向异性扩展。

3.3 与 Lambert / Oren-Nayar 的对比

模型 物理基础 边缘行为 性能 工业地位
Lambert 理想散射假设 边缘正常 极快 移动端默认
Oren-Nayar V 形凹槽统计 强 retro-reflection 慢(含 sin/tan) 学术 / 月球渲染
Disney Diffuse 经验拟合 中等 retro-reflection 中等(两次 pow5) 工业主流

Disney Diffuse 在视觉上对粗糙塑料、布料的边缘呈现做了显著改善,并被 UE4 采纳。但其严格能量守恒并不成立(粗糙度高时会有少量能量增益),路径追踪渲染器通常会做后处理归一化或换用 Oren-Nayar。

1
2
3
4
5
6
7
8
// Disney Diffuse 工程实现
float Fd_Burley(float NoV, float NoL, float LoH, float roughness)
{
float f90 = 0.5 + 2.0 * roughness * LoH * LoH;
float lightScatter = F_Schlick(NoL, 1.0, f90);
float viewScatter = F_Schlick(NoV, 1.0, f90);
return lightScatter * viewScatter * (1.0 / PI);
}

四、Disney Specular 项

Disney specular 严格遵循 Cook-Torrance 框架:

具体选型:

  • NDF (D):GGX
  • Geometry (G):Smith G with GGX-derived ,部分实现使用 Heitz 的 Joint Smith
  • Fresnel (F):Schlick 近似

4.1 关键设计:roughness 重映射

Disney 引入了一个看似细节但极重要的工程决策——感知线性粗糙度

这个平方映射有一个直观理由:在 GGX 中,从 的视觉差异远大于从 。如果直接将美术参数对应到 ,则 00.05 这一区间会”过快变化”,而 0.51.0 这一区间会”几乎无变化”。

1
float roughness = perceptualRoughness * perceptualRoughness;

这个约定后来被 UE4、Filament、Unity URP 全部继承,构成了所有现代 PBR 资产的隐含假设。

4.2 的双控

对于电介质,specular 参数计算:

specular = 0.5 对应 (玻璃/塑料),specular = 0.7 对应 (宝石)。

1
vec3 f0 = 0.16 * reflectance * reflectance * (1.0 - metallic) + baseColor * metallic;

五、各向异性(Anisotropic)

5.1 物理动机

GGX 与所有前述 NDF 都假设法线分布关于宏观法线轴对称(各向同性)。但拉丝金属、唱片、人发、丝绸等材质的表面具有方向性微沟槽,高光会沿垂直于沟槽的方向被拉长——这就是各向异性

5.2 切线空间粗糙度分离

Disney 的转化公式将单一 拆分为切线方向 与副切线方向

或使用 Burley 在 2015 年改进的面积守恒形式:

5.3 Anisotropic GGX NDF

将 GGX 推广到椭球微面分布:

其中 分别是切线与副切线。当 时退化为各向同性 GGX。

1
2
3
4
5
6
7
8
9
10
float D_GGX_Anisotropic(float NoH, float3 H, float3 T, float3 B, float at, float ab)
{
float ToH = dot(T, H);
float BoH = dot(B, H);
float a2 = at * ab;
float3 v = float3(ab * ToH, at * BoH, a2 * NoH);
float v2 = dot(v, v);
float w2 = a2 / v2;
return a2 * w2 * w2 * (1.0 / PI);
}

5.4 各向异性 Smith G

为保持能量守恒,G 项也必须同步拉伸。 函数变为:

工程上常将 D 与 V 项合并为 DV_SmithJointGGXAniso 单一函数,节省运算:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
half DV_SmithJointGGXAniso(half ToH, half BoH, half NoH, 
half ToV, half BoV, half NoV,
half ToL, half BoL, half NoL,
half aT, half aB)
{
half a2 = aT * aB;
half3 v = half3(aB * ToH, aT * BoH, a2 * NoH);
half v2 = dot(v, v);
half w2 = a2 / v2;
half D = a2 * w2 * w2 * INV_PI;

half lambdaV = NoL * length(half3(aT * ToV, aB * BoV, NoV));
half lambdaL = NoV * length(half3(aT * ToL, aB * BoL, NoL));
half V = 0.5 / (lambdaV + lambdaL);

return D * V;
}

5.5 各向异性方向贴图

美术常通过流向贴图(Flow Map / Tangent Map)控制各向异性方向,shader 中将其与原 TBN 切线进行旋转:

1
2
3
float2 anisoDir = SAMPLE_TEXTURE2D(_AnisoMap, sampler_AnisoMap, uv).rg * 2.0 - 1.0;
float3 anisoTangent = normalize(anisoDir.x * tangentWS + anisoDir.y * bitangentWS);
float3 anisoBitangent = cross(normalWS, anisoTangent);

移动端简化常用 Kajiya-Kay 模型替代——其本质是 Phong 形式的各向异性高光,不严格 PBR 但成本只有 GGX 各向异性的零头:

适用于低端设备的头发与简单拉丝金属。


六、Sheen 项

6.1 设计目标

Disney 引入 sheen 是为了表现两种现实现象:

  1. 布料的边缘泛光:天鹅绒、丝绒在掠射角呈现明亮的环带;
  2. 电介质 specular 的能量补偿:粗糙电介质 specular 部分在低强度下能量损失,sheen 作为一个”附加薄层”补偿。

6.2 公式

Disney 原始 sheen:

其中 sheenTint 在白色与 baseColor 之间插值得到。这个公式本质上是 Schlick 形式的 控制,配合一个低能 Lambert-like 分布。

1
2
3
4
float3 c_lin = mon2lin(baseColor);
float3 c_tint = lum > 0 ? c_lin / lum : float3(1, 1, 1);
float3 c_sheen = lerp(float3(1, 1, 1), c_tint, sheenTint);
float3 Fsheen = sheen * c_sheen * pow(1 - LoH, 5);

注意:Disney 原始的 sheen 仅是一个”边缘亮一下”的近似,并不严格基于布料的微表面物理。后来 Estevez & Kulla 在 2017 年提出 Charlie 分布作为完整的布料 NDF,比 Disney sheen 物理更准确——这部分会在第四篇详细展开。


七、Clearcoat(清漆层)

7.1 物理模型

汽车漆、塑料烤漆、亮光木材等材质,底层金属/染料之上覆盖了一层透明清漆。Clearcoat 模型将材质拆分为:

  • Coat Layer:各向同性的薄膜,IOR ≈ 1.5(聚氨酯类聚合物),
  • Base Layer:底层 BRDF(可能是金属、染色塑料、织物等任意 BRDF)。

7.2 公式

Disney clearcoat 用的是一个独立的 GTR1 分布(Generalized Trowbridge-Reitz, ),相对于 GGX()有更长的尾部:

其中 clearcoatGloss 在 [0.1, 0.001] 之间反向映射(gloss 越高, 越小)。

最朴素的能量分配(不考虑层间多次反射):

注意要同时衰减入射光和出射光——光必须穿过清漆两次。

7.3 工程实现细节

工程上更精细的实现还需考虑:

  1. 法线解耦:清漆层与底层可以拥有独立的法线贴图(车漆的清漆层近乎平滑,但底层可能有细微凹凸);
  2. 吸收(Absorption):清漆若有色(如琥珀色木漆),需对穿透的光按 Beer-Lambert 衰减:
  3. 能量补偿:底层因清漆遮蔽而变暗的视觉效果需用 Kulla-Conty 类方法修正(详见第五篇)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
half3 ClearCoatBRDF(BRDFData base, BRDFData coat, half3 L, half3 V, 
half3 N, half3 Ncoat, half clearcoatStrength)
{
// 1. 清漆层 BRDF(IOR=1.5, F0=0.04,固定)
half3 H = normalize(L + V);
half NoH = saturate(dot(Ncoat, H));
half NoV = saturate(dot(Ncoat, V));
half NoL = saturate(dot(Ncoat, L));
half VoH = saturate(dot(V, H));

half D = D_GTR1(NoH, lerp(0.1, 0.001, coat.roughness));
half V_coat = V_Kelemen(VoH);
half Fc = F_Schlick(VoH, 0.04);
half3 specCoat = D * V_coat * Fc * 0.25 * clearcoatStrength;

// 2. 底层 BRDF
half3 baseColor = DirectBRDF(base, N, L, V);

// 3. 双向衰减合成
half3 attenuation = (1.0 - Fc * clearcoatStrength)
* (1.0 - F_Schlick(saturate(dot(Ncoat, L)), 0.04) * clearcoatStrength);
return specCoat + baseColor * attenuation;
}

八、Subsurface(次表面散射近似)

Disney 2012 的 subsurface 是对 Hanrahan-Krueger 的近似,将其作为漫反射的一个 lerp 目标:

最终漫反射用 subsurface 参数在 Disney Diffuse 与 SSS 近似之间插值:

注意:这只是一个廉价近似,并不模拟真正的次表面散射光路。真正的物理 SSS(Burley 归一化扩散、Separable SSS、预积分皮肤)会在第五篇专题展开。Disney 此处只是”在便宜的代价下让玉石、蜡、皮肤看起来稍微温暖一点”。


九、Disney 2015 BSDF 扩展

Burley 在 SIGGRAPH 2015 课程 “Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering” 中将原 BRDF 扩展为完整 BSDF,主要新增:

9.1 新增参数

参数 含义
specTrans 镜面透射强度(玻璃、水)
ior 折射率(默认 1.5)
flatness 薄表面(树叶、纸)的额外漫反射形状参数
diffTrans 漫反射透射(薄半透明)
scatterDistance 次表面散射距离(替代之前的 subsurface 近似)

9.2 透射 BTDF

对镜面透射(厚介质),同样基于 GGX 但使用透射半角向量:

9.3 真正的 SSS:Burley 归一化扩散

2015 论文用 Burley 自己提出的归一化扩散剖面替换 2012 的廉价近似:

其中 是入射点到出射点的距离, 是平均散射距离, 是与表面反照率相关的形状参数。这个剖面在屏幕空间或纹理空间被卷积到漫反射结果上——详见第五篇。

工程上常用如下解析评估(避免数值积分):

1
2
3
4
5
6
7
8
9
// Burley 2015: 归一化扩散剖面解析评估
// A: surface albedo, s: shape parameter, d: scatter distance, r: planar distance
float3 BurleyNormalizedDiffusion(float3 A, float3 s, float3 d, float r)
{
// 单根曲线:两个指数衰减的加权和
float3 expTerm1 = exp(-s * r / d);
float3 expTerm2 = exp(-s * r / (3.0 * d));
return A * s * (expTerm1 + expTerm2) / (8.0 * PI * r);
}

参数 s 由表面反照率 拟合得到(Burley 给出经验公式 ),美术只需提供 albedoscatterDistance,无需理解扩散方程。

9.4 薄表面(Thin Surface)

对于树叶、纸、布等”薄”材质,2015 引入了 thin 模式:

  • 镜面透射改为薄表面扁平变换;
  • 漫反射 + diffTrans 实现双向 wrap lighting;
  • subsurface 退化为 hemisphere blur(无需真正的 BSSRDF)。

核心代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Disney 2015: 薄表面(Thin Surface)漫反射透射近似
// 结合表面粗糙度与次表面散射特征,用于树叶、纸张等薄片材质
float3 Disney2015_ThinDiffuse(float NdotL, float NdotV, float LdotV, float roughness)
{
float FL = SchlickFresnel(NdotL);
float FV = SchlickFresnel(NdotV);

// 模拟光线穿透薄表面的能量分布;roughness 越高,透射越发散
float Fd90 = 0.5 + 2.0 * roughness * LdotV * LdotV;
float Fd = lerp(1.0, Fd90, FL) * lerp(1.0, Fd90, FV);

// 透射方向的 Lambert 近似
return (1.0 / PI) * Fd;
}

2015 BSDF 的工程意义在于它统一了反射(Reflection)和透射(Transmission)——同一套参数(baseColor、roughness、metallic 等)能驱动正反两面的光学表现,无需为半透明材质开辟独立的 shader 模型。这为后续 glTF KHR_materials_transmission、KHR_materials_volume 等扩展奠定了基础。


十、完整 HLSL 参考实现(Disney 2012 BRDF)

下面是 Disney BRDF 完整的参考实现,移植自 wdas/brdf 的官方源码。这是面试和深度学习时的”教科书版本”:

HLSL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
float SchlickFresnel(float u)
{
float m = saturate(1.0 - u);
float m2 = m * m;
return m2 * m2 * m;
}

float GTR1(float NdotH, float a)
{
if (a >= 1.0) return 1.0 / PI;
float a2 = a * a;
float t = 1.0 + (a2 - 1.0) * NdotH * NdotH;
return (a2 - 1.0) / (PI * log(a2) * t);
}

float GTR2(float NdotH, float a)
{
float a2 = a * a;
float t = 1.0 + (a2 - 1.0) * NdotH * NdotH;
return a2 / (PI * t * t);
}

float GTR2_Aniso(float NdotH, float HdotX, float HdotY, float ax, float ay)
{
float t = (HdotX / ax) * (HdotX / ax)
+ (HdotY / ay) * (HdotY / ay)
+ NdotH * NdotH;
return 1.0 / (PI * ax * ay * t * t);
}

float SmithG_GGX(float NdotV, float alphaG)
{
float a = alphaG * alphaG;
float b = NdotV * NdotV;
return 1.0 / (NdotV + sqrt(a + b - a * b));
}

float SmithG_GGX_Aniso(float NdotV, float VdotX, float VdotY, float ax, float ay)
{
return 1.0 / (NdotV + sqrt(pow(VdotX * ax, 2)
+ pow(VdotY * ay, 2)
+ pow(NdotV, 2)));
}

float3 DisneyBRDF(float3 L, float3 V, float3 N, float3 X, float3 Y,
float3 baseColor, float metallic, float roughness,
float specular, float specularTint, float anisotropic,
float sheen, float sheenTint,
float clearcoat, float clearcoatGloss, float subsurface)
{
float NdotL = dot(N, L);
float NdotV = dot(N, V);
if (NdotL < 0 || NdotV < 0) return float3(0, 0, 0);

float3 H = normalize(L + V);
float NdotH = dot(N, H);
float LdotH = dot(L, H);

float3 Cdlin = baseColor;
float Cdlum = 0.3 * Cdlin.r + 0.6 * Cdlin.g + 0.1 * Cdlin.b;
float3 Ctint = Cdlum > 0 ? Cdlin / Cdlum : float3(1, 1, 1);
float3 Cspec0 = lerp(specular * 0.08 * lerp(float3(1, 1, 1), Ctint, specularTint),
Cdlin, metallic);
float3 Csheen = lerp(float3(1, 1, 1), Ctint, sheenTint);

// Diffuse: Lambert + retro-reflection + subsurface approximation
float FL = SchlickFresnel(NdotL);
float FV = SchlickFresnel(NdotV);
float Fd90 = 0.5 + 2 * LdotH * LdotH * roughness;
float Fd = lerp(1.0, Fd90, FL) * lerp(1.0, Fd90, FV);

// Hanrahan-Krueger subsurface approximation
float Fss90 = LdotH * LdotH * roughness;
float Fss = lerp(1.0, Fss90, FL) * lerp(1.0, Fss90, FV);
float ss = 1.25 * (Fss * (1.0 / (NdotL + NdotV) - 0.5) + 0.5);

// Specular
float aspect = sqrt(1.0 - anisotropic * 0.9);
float ax = max(0.001, roughness * roughness / aspect);
float ay = max(0.001, roughness * roughness * aspect);
float Ds = GTR2_Aniso(NdotH, dot(H, X), dot(H, Y), ax, ay);
float FH = SchlickFresnel(LdotH);
float3 Fs = lerp(Cspec0, float3(1, 1, 1), FH);
float Gs = SmithG_GGX_Aniso(NdotL, dot(L, X), dot(L, Y), ax, ay)
* SmithG_GGX_Aniso(NdotV, dot(V, X), dot(V, Y), ax, ay);

// Sheen
float3 Fsheen = FH * sheen * Csheen;

// Clearcoat (IOR = 1.5, F0 = 0.04)
float Dr = GTR1(NdotH, lerp(0.1, 0.001, clearcoatGloss));
float Fr = lerp(0.04, 1.0, FH);
float Gr = SmithG_GGX(NdotL, 0.25) * SmithG_GGX(NdotV, 0.25);

return ((1.0 / PI) * lerp(Fd, ss, subsurface) * Cdlin + Fsheen)
* (1.0 - metallic)
+ Gs * Fs * Ds
+ 0.25 * clearcoat * Gr * Fr * Dr;
}

这份代码是行业的”Hello World”。读懂它的每一行,几乎等于读懂了现代实时 PBR 的所有数学。


十一、工业地位与延伸

Disney Principled BRDF 之后的所有工业 PBR 实现,都是它的”剪裁版本”:

引擎/库 剪裁策略
UE4 移除 sheen + clearcoatGloss 简化为单一 clearcoat;roughness 保留,引入 Specular 通道;保留 anisotropic、subsurface
Filament 默认 lit 模型只保留 baseColor / metallic / roughness / reflectance;anisotropic / clearcoat / sheen 通过子模型扩展
Unity URP Lit 默认更精简:metallic / smoothness(= 1 - roughness)/ specular(specular workflow);clearcoat、anisotropic 需 HDRP 或自定义
glTF 2.0 PBR 标准化为 metallic-roughness + 多个 KHR 扩展(KHR_materials_clearcoat、sheen、anisotropy、transmission、ior)

十二、Disney 2012 的物理妥协与后续修正

Disney 2012 BRDF 在工业界被广泛奉为标准,但它本身并非严格能量守恒的物理模型——这是一个常被忽略、却在图形学面试与精确路径追踪中至关重要的事实。

12.1 能量过冲问题

回顾 Disney 2012 的合成公式(见第十节代码末尾):

注意 Disney 并没有在 diffuse 项前乘 ——这是第一篇 9.4 节 Shirley 能量耦合公式的关键项。这意味着:

  • 当粗糙度较高且处于掠射角时(),specular 接近全反射;
  • 同时 Disney Diffuse 因 retro-reflection 也会被 增强;
  • 两者相加可能超过入射能量(即反射出的光比打进去的还多)。

实测数据:roughness = 0.8、视线接近掠射角时,Disney BRDF 的能量超出 1.0 的幅度可达 5-15%,肉眼表现为材质边缘”过曝发亮”。

12.2 工业修正方案

后续主流引擎对此问题的修正路线:

Frostbite (2014):在 diffuse 前显式乘

1
2
float3 diffuseEnergy = 1.0 - max3(F_Schlick(NoL, F0));  // 或更严谨的方向平均
float3 Fd = diffuseEnergy * baseColor / PI * disneyDiffuseTerm;

UE4:通过预积分 BRDF LUT 中的 scale + bias 通道隐式分配能量(详见第三篇 Split Sum);

Filament:使用 EnvironmentBRDF 函数将 specular 与 diffuse 的能量分配前置到 BRDFData 初始化阶段:

1
diffuseColor = (1.0 - metallic) * baseColor;  // 物理上仍是近似,但避免运行时反复扣除

HDRP / Disney 2015 BSDF:通过引入透射通道(specTrans),从根本上重写了能量分配:被反射的、被折射的、被薄表面透射的三部分严格互斥。

12.3 经验性参数 vs 物理量

Disney 论文反复强调”艺术导向”,这是其被工业接纳的核心优势,但也意味着部分参数与物理量之间存在折中:

参数 物理量 妥协
subsurface 散射强度 仅是 diffuse 与 Hanrahan-Krueger 近似的 lerp 权重,不模拟真实光路
sheen 微纤维散射 仅是 Schlick pow5 的颜色叠加,无微表面物理基础
clearcoat 双层 BRDF 强度 用 0.25 系数手动衰减,未严格做层间能量守恒

结论:Disney 2012 BRDF 是艺术友好性优先于物理严谨性的工业模型。在实时游戏中其偏差可接受;在精确路径追踪(Arnold、Mantra、Cycles)中,引擎通常会对各项做能量守恒后处理或重新参数化。理解这一点,才能在 Disney 框架与”更物理”的 Layered BSDF(第五篇 SpongeCake)之间做出合适的工程选择。


十三、工程调试

验证 Disney 实现是否能量守恒

最快的方法仍是白炉测试(详见第三篇 6.1 节)。对纯白电介质(baseColor = 1.0, metallic = 0, specular = 0.5),不同 roughness 下的输出:

roughness 单纯 Disney 2012 + Frostbite 修正 期望
0.1 0.99 0.99 ≤ 1.0
0.5 1.04 ← 超出 0.97 ≤ 1.0
0.9 1.13 ← 显著超出 0.93 ≤ 1.0

如果实测发现高粗糙度下能量超过 1.0,说明 diffuse 没做 衰减——必加。

各向异性 NaN 排查

GTR2_Aniso 中如果 axay 为 0,分母会爆炸。务必:

1
2
float ax = max(0.001, roughness * roughness / aspect);
float ay = max(0.001, roughness * roughness * aspect);

Sheen 与 Specular 的双计能量

如果同时启用 sheen 和默认的 specular,且粗糙度较高时,两者在掠射角会”双重计数”边缘高光。建议用 sheen 时压低 specular 通道,或仅在粗糙布料类材质上启用。

subsurface = 1.0 的边界异常

Disney subsurface 参数本质是 lerp,但当 = 1.0 时,diffuse 完全替换为 Hanrahan-Krueger 近似——它在 NoL + NoV → 0 时分母接近 0,需 clamp:

1
float ss = 1.25 * (Fss * (1.0 / max(NoL + NoV, 1e-3) - 0.5) + 0.5);

十四、本篇总结

Disney Principled BRDF 的真正价值:

  1. 建立了参数化标准:BaseColor / Metallic / Roughness 三件套,跨引擎可移植;
  2. 整合了多个 BRDF 项:Diffuse / Specular / Sheen / Clearcoat / Anisotropic / Subsurface 在一个统一公式下共存;
  3. 2015 BSDF 扩展补全了透射、薄表面、真实 SSS;
  4. 后续所有 PBR 创新——Charlie sheen、Kulla-Conty 补偿、SpongeCake 分层——都是在 Disney 框架的”留白”上添砖加瓦;
  5. 它不是终点——Disney 自身的能量过冲问题、subsurface 的物理粗糙近似、clearcoat 层间耦合的简化,都是后续工作要继续修补的地方。

下一篇我们看这套理论如何被 Karis 的 Split Sum、Filament 的标准模型、Unity URP 的源码具体落地——把数学变成 GPU 上每帧 60 次的指令流。


参考文献

  1. Burley, B. (2012). Physically Based Shading at Disney. SIGGRAPH Course.
  2. Burley, B. (2015). Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering. SIGGRAPH Course.
  3. Walt Disney Animation Studios. BRDF Explorer. GitHub.
  4. Karis, B. (2013). Real Shading in Unreal Engine 4. SIGGRAPH Course.
  5. Lagarde, S. & de Rousiers, C. (2014). Moving Frostbite to Physically Based Rendering. SIGGRAPH Course.
  6. QianMo. PBR-White-Paper. GitHub.
  7. 【渲染】Disney BSDF 深度解析 | 知乎.