Administrator
发布于 2026-09-09 / 33 阅读
0
0

理解 BRDF

下面把前面的内容收束成一套可以直接对应 Shader 实现的完整 BRDF。

这里采用游戏引擎最常见的一套:

Metallic-Roughness PBR + Lambert Diffuse + Cook-Torrance GGX Specular

严格来说这不是完整的 Disney 2012 BRDF,但它就是 Unity、Unreal、glTF 等现代实时 PBR 的核心骨架。


1. 最终要算什么

对一个像素,一盏灯产生的直接光照:

\[L_o = (L_{diffuse}+L_{specular}) \times L_i \times (N\cdot L)\]

其中:

变量 来历 含义
\(L_o\) 最终计算 当前像素向摄像机反射的光
\(L_i\) 光源 光源颜色 × 强度
\(N\) Mesh/Normal Map 表面法线
\(L\) 光源位置 像素 → 光源的单位向量
\(V\) Camera 像素 → 摄像机的单位向量

最后的:

\[N\cdot L\]

就是最基本的 Lambert 余弦定律:

光越垂直照射表面,单位面积收到的能量越多。

【PBR思想:物理正确的入射光能量】


2. 美术真正提供的三个核心参数

通常材质贴图给:

\[BaseColor,\quad Metallic,\quad Roughness\]

其中:

BaseColor  ← BaseColor Texture
Metallic   ← Metallic Texture
Roughness  ← Roughness Texture
Normal     ← Normal Map

它们不是直接对应 D、F、G,而是进一步参与 BRDF。


3. 先准备几个几何向量

已经有:

\[N,L,V\]

再计算半程向量:

\[H=\frac{L+V}{|L+V|}\]

也就是:

光线方向和观察方向的中间方向。

为什么需要 H?

因为微表面模型认为:

只有法线方向刚好接近 H 的微小镜面,才能把 L 方向来的光反射进 V。

所以 H 是 Cook-Torrance 的重要几何变量。


4. Roughness → 微表面粗糙度 α

一般不会直接把 Roughness 塞进 GGX。

常见做法:

\[\alpha = Roughness^2\]

Roughness 来源:

\[Roughness = Texture_{roughness}\]

为什么平方?

因为直接线性使用 Roughness,视觉变化不够均匀。

平方之后:

美术拖动 Roughness 参数时,视觉响应更加符合直觉。

注意不同引擎具体映射可能略有区别。

【PBR思想:材质参数有统一、稳定的物理意义】


5. 计算 D:GGX 微表面分布

Cook-Torrance Specular:

\[f_{specular} = \frac{DGF} {4(N\cdot L)(N\cdot V)}\]

先看 D:

\[D_{GGX} = \frac{\alpha^2} {\pi \left[ (N\cdot H)^2(\alpha^2-1)+1 \right]^2}\]

变量:

变量 来历
\(N\) Mesh Normal / Normal Map
\(H\) 根据 L 和 V 计算
\(\alpha\) \(Roughness^2\)
\(\pi\) 数学常数

D 回答的问题:

当前表面上,有多少微小镜面正好朝着 H?


D 的物理意义

Roughness 很低:

微表面方向高度一致

///////////

于是满足正确方向的微表面非常集中。

结果:

高光小、尖、亮。

Roughness 高:

/\/\_/\/\_/\

微表面方向非常分散。

结果:

高光大、宽、弱。

所以:

\[Roughness\rightarrow\alpha\rightarrow D\]

【PBR思想:Microfacet 微表面理论】

这比 Blinn-Phong 的:

\[(N\cdot H)^{Shininess}\]

先进的地方就是:

Blinn-Phong 在人为画高光;

GGX 在模拟微观表面方向分布。


6. BaseColor + Metallic → F₀

接下来是 Fresnel。

先计算一个非常重要的量:

\[F_0\]

代表:

垂直观察材质时的基础镜面反射率。

对于普通非金属,常见近似:

\[F_0\approx0.04\]

也就是 RGB:

\[(0.04,0.04,0.04)\]

现代 Metallic Workflow 通常写:

\[F_0 = lerp(0.04,BaseColor,Metallic)\]

也可以展开:

\[F_0= 0.04(1-Metallic) + BaseColor\times Metallic\]


非金属

如果:

\[Metallic=0\]

那么:

\[F_0=0.04\]

例如红塑料:

BaseColor = 红色
Metallic = 0

Diffuse = 红色
Specular F0 ≈ 白色 4%

金属

如果:

\[Metallic=1\]

那么:

\[F_0=BaseColor\]

例如黄金:

BaseColor = 金黄色
Metallic = 1

Diffuse ≈ 0
Specular = 金黄色

因此金属反射本身具有颜色。

【PBR思想:金属和非金属遵循不同的真实光学行为】


7. F:Schlick Fresnel

有了 \(F_0\),计算:

\[F = F_0+ (1-F_0) (1-V\cdot H)^5\]

这就是常用的 Schlick Fresnel approximation。

变量来源:

变量 来源
\(F_0\) BaseColor + Metallic
\(V\) Camera
\(H\) L + V 得到

F 回答:

当前观察角度下,有多少光直接被表面镜面反射?

正面看:

\[V\cdot H\approx1\]

所以:

\[F\approx F_0\]

掠射角:

\[V\cdot H\rightarrow0\]

于是:

\[F\rightarrow1\]

也就是说:

几乎所有材质在非常倾斜的角度看过去,反射都会明显增强。

这就是水面、玻璃、塑料边缘变亮的原因。

【PBR思想:Fresnel 物理规律】


8. G:Geometry Shadowing / Masking

微表面不仅方向不同,它们还会互相遮挡。

因此需要:

\[G\]

回答:

即使某个微表面方向正确,它有没有被别的微表面挡住?

常见实时实现使用 Smith GGX:

\[G(N,V,L)= G_1(N,V)\times G_1(N,L)\]

一种常见形式:

\[G_1(N,X) = \frac{N\cdot X} {(N\cdot X)(1-k)+k}\]

其中:

\[k=\frac{(Roughness+1)^2}{8}\]

因此:

\[G= G_1(N,V) G_1(N,L)\]

这里:

Roughness
   ↓
   k

N·V → Camera方向遮挡

N·L → Light方向遮挡

G 处理两件事情:

Masking
微表面反射出来的光被挡住

Shadowing
光进入微表面之前被挡住

【PBR思想:Microfacet 几何自遮挡】


9. 得到完整 Cook-Torrance Specular

现在终于把 D、F、G 合起来:

\[\boxed{ f_{specular} = \frac{D_{GGX}\times F\times G} {4(N\cdot L)(N\cdot V)} }\]

这就是核心。

可以直接记:

\[\boxed{CookTorrance=\frac{DFG}{4N_LN_V}}\]

其中:

Roughness
   ↓
α
├──→ D:微表面朝向分布
└──→ G:微表面互相遮挡


BaseColor + Metallic
          ↓
          F0
          ↓
          F:Fresnel反射


N / L / V
   ↓
影响 D、F、G

分母:

\[4(N\cdot L)(N\cdot V)\]

并不是随便加的修正项。

它来自微表面 BRDF 的几何变换和归一化:

把微表面法线空间中的能量转换成宏观表面的反射能量。

【PBR思想:BRDF 能量和概率分布正规化】


10. Specular 有了,还需要 Diffuse

对于最简单 Lambert:

\[f_{Lambert} = \frac{BaseColor}{\pi}\]

为什么除以:

\[\pi\]

因为漫反射向整个上半球散射。

如果不除 \(\pi\),把所有方向上的输出光积分起来,会凭空得到过多能量。

所以:

\[\frac{1}{\pi}\]

非常重要。

【PBR思想:能量守恒】


11. Fresnel 决定 Diffuse 还能分多少能量

现在假设:

\[F=0.2\]

说明约有 20% 的当前光能已经进入镜面反射。

那么剩下最多:

\[1-F=0.8\]

可以用于 Diffuse。

所以定义:

\[k_S=F\]

Specular 权重。

然后:

\[k_D=1-k_S\]

但金属不能有普通漫反射。

所以进一步:

\[\boxed{ k_D=(1-F)(1-Metallic) }\]

这是 Metallic-Roughness PBR 中非常核心的一步。


非金属

例如:

\[Metallic=0\]

于是:

\[k_D=1-F\]

镜面反射走掉多少能量,Diffuse 就相应少掉多少。


金属

如果:

\[Metallic=1\]

那么:

\[k_D=0\]

所以:

\[Diffuse=0\]

能量主要进入 Specular。

这就不是:

Diffuse 随便算一个
+
Specular 再随便算一个

而是:

             Incoming Light
                    ↓
               Fresnel F
               /       \
              /         \
       Specular       剩余能量
                         ↓
                  × (1-Metallic)
                         ↓
                      Diffuse

【PBR思想:能量守恒】


12. 完整 Diffuse BRDF

所以:

\[f_{diffuse} = k_D \frac{BaseColor}{\pi}\]

即:

\[\boxed{ f_{diffuse} = (1-F)(1-Metallic) \frac{BaseColor}{\pi} }\]


13. 最终完整 BRDF

现在:

\[BRDF = f_{diffuse} + f_{specular}\]

即:

\[\boxed{ BRDF = (1-F)(1-Metallic) \frac{BaseColor}{\pi} + \frac{DGF} {4(N\cdot L)(N\cdot V)} }\]

这基本就是你现在最值得记住的一条完整公式。

然后一盏灯真正贡献给像素的颜色:

\[\boxed{ L_o= BRDF \times L_i \times \max(N\cdot L,0) }\]

多盏灯就是求和:

\[L_o= \sum_i BRDF_i L_i (N\cdot L_i)\]

之后还可以加:

IBL
Emission
AO
Shadow
Reflection Probe
GI

最后:

HDR Color
↓
Tone Mapping
↓
屏幕

14. 把整个 Shader 数据流串起来

材质贴图
────────────────────────────

BaseColor ────────────────┐
                         │
Metallic ───┐             │
            ↓             ↓
       F0 = lerp(0.04, BaseColor, Metallic)
            │
            ↓
         Fresnel
            │
            ↓
            F
            │
       ┌────┴─────┐
       ↓          ↓
 Specular      Diffuse权重
              (1-F)
                 │
          × (1-Metallic)
                 ↓
                kD


Roughness
    ↓
Roughness²
    ↓
    α
   / \
  ↓   ↓
 GGX  Geometry
  D      G


Camera ──→ V ───┐
                 │
Light ───→ L ────┼──→ H = normalize(L+V)
                 │
Normal ───→ N ───┘


                 ↓

      Cook-Torrance Specular

               D × F × G
          ─────────────────
          4(N·L)(N·V)

                 +

          kD × BaseColor
          ──────────────
                 π

                 ↓

                BRDF

                 ↓

          × Light Radiance

                 ↓

              × N·L

                 ↓

            Pixel Lighting

15. 这套公式体现了哪些 PBR 思想

PBR设计思想 在公式里的体现
微表面理论 GGX \(D\)
真实粗糙度 Roughness → α → D/G
Fresnel规律 \(F\)
微观遮挡 Geometry \(G\)
金属/非金属模型 Metallic
物理基础反射率 \(F_0\)
能量守恒 \(k_D=(1-F)(1-Metallic)\)
漫反射正规化 \(BaseColor/\pi\)
入射能量符合余弦定律 \(N\cdot L\)
材质与灯光解耦 BaseColor / Metallic / Roughness 有稳定意义

最后用一句话理解整套 BRDF

你可以把 Cook-Torrance PBR 想成:

Roughness 告诉我表面微观上有多乱;GGX 的 D 算多少微表面正好朝对方向;G 算这些微表面有没有被挡住;BaseColor + Metallic 决定 F₀;Fresnel 的 F 决定这个观察角度到底反射多少;剩余能量才能进入 Diffuse,最终共同组成这个像素的 BRDF。

最值得真正记住的是这三条:

\[\boxed{ F_0=lerp(0.04,BaseColor,Metallic) }\]

\[\boxed{ f_s=\frac{DGF}{4(N\cdot L)(N\cdot V)} }\]

\[\boxed{ BRDF=(1-F)(1-Metallic)\frac{BaseColor}{\pi}+f_s }\]

理解这三条以后,现代游戏 PBR 的主体框架基本就已经通了。


评论