Base-PBR
PBR(Physically Based Rendering,基于物理的渲染)不是某一个固定 Shader,而是一套尽量遵循真实光照规律的材质与渲染方法。
它的目标不是绝对还原现实,而是让材质满足一些稳定的物理约束:
- 同一份材质换到不同光照环境中,仍然能保持合理的外观。
- 材质参数有明确含义,而不是靠随意调颜色凑效果。
- 表面反射的能量不能凭空增加。
- 金属、非金属、粗糙和光滑表面能够用统一模型表达。
目前游戏引擎常见的 PBR,一般指基于微表面理论的 Cook-Torrance BRDF,再配合金属度工作流和基于图像的环境光照。
1. 光照计算到底在算什么
光线到达表面后,大致会发生两类事情:
- 一部分光在表面直接反射,形成镜面反射(Specular)。
- 一部分光进入材质内部,被吸收或经过散射后重新射出,形成漫反射(Diffuse)。
我们最终计算的是:从光源方向 L 入射的光,有多少能量会沿观察方向 V 离开表面。
常用方向定义:
N:宏观表面法线。L:表面指向光源的方向。V:表面指向相机的方向。H:L + V归一化后的半程向量。
1 | |
如果某个微表面的法线刚好朝向 H,它就能把来自 L 的光反射到 V。
2. 渲染方程与 BRDF
反射方程可以简化理解为:
1 | |
Lo:从表面沿观察方向离开的光。Le:表面自己发出的光,例如自发光。Li:从某个方向到达表面的光。fr:BRDF,描述表面如何把入射光反射到观察方向。N · L:光线与表面的夹角衰减。∫Ω:把上半球所有方向的入射光贡献加起来。
实时渲染不可能对无限方向做完整积分,所以会对直接光逐灯计算,并用预计算、探针或近似算法处理环境间接光。
2.1 BRDF 是什么
BRDF(Bidirectional Reflectance Distribution Function,双向反射分布函数)不是一张贴图,而是一个函数:
1 | |
一个物理合理的 BRDF 通常应满足:
- 能量守恒:反射出去的能量不应大于入射能量。
- 互易性:交换入射与观察方向,结果不变。
实时 PBR 通常把 BRDF 分成漫反射和镜面反射:
1 | |
3. 微表面理论
真实表面在微观上并不平整。PBR 把宏观表面看成大量方向不同的微小镜面。
- 光滑表面的微表面朝向集中,反射光集中,高光小而清晰。
- 粗糙表面的微表面朝向分散,反射光分散,高光宽而模糊。
粗糙度描述的是微表面法线分布范围,不是简单降低高光亮度。粗糙表面的高光峰值通常会降低,但覆盖范围会扩大,整体能量不应该凭空消失。
4. Cook-Torrance 镜面 BRDF
常见的 Cook-Torrance 微表面镜面项为:
1 | |
其中:
D:微表面法线分布。F:菲涅尔反射。G:微表面之间的遮蔽与阴影。- 分母:对微表面投影面积进行归一化。
实际实现时所有点积都需要限制到合理范围,并处理分母接近 0 的情况。
4.1 D:Normal Distribution Function
D 描述微表面法线有多少朝向半程向量 H。
游戏中常用 GGX / Trowbridge-Reitz 分布。它相比一些早期分布具有更长的高光尾部,更接近许多真实材质:
1 | |
α 由感知粗糙度转换而来,常见做法是:
1 | |
这里的平方是参数映射,并不代表所有引擎的贴图通道都以同样方式存储。跨引擎传递材质时,要确认 Smoothness、Roughness 和内部 α 的转换规则。
4.2 F:Fresnel
菲涅尔效应表示反射率随观察角度变化:越接近掠射角,表面反射通常越强。
实时渲染常用 Schlick 近似:
1 | |
F0 是垂直观察表面时的基础反射率,也是本节要重点解释的概念。
4.2.1 基础反射率 F0 详解
定义:垂直入射时的菲涅尔反射率
F0 的物理含义是:光线垂直入射(N·V = 1,视线与表面法线平行)时,有多少比例的光被直接反射出去。整个菲涅尔曲线以 F0 为”起点”——随着视角转向掠射角,反射率只会从 F0 上升,不会低于它。
物理根源:与折射率(IOR)的关系
F0 的数值来自材质的折射率。当光线从一种介质进入另一种时,垂直入射的反射率由两种介质的折射率决定:
1 | |
光线从空气(n ≈ 1.0)射入材质表面时简化为:
1 | |
常见材质的 IOR 与对应的 F0:
| 材质 | 折射率(IOR) | F0 |
|---|---|---|
| 水 | 1.33 | 0.02 |
| 玻璃 | 1.5 | 0.04 |
| 塑料(常见) | ~1.5 | ~0.04 |
| 钻石 | 2.42 | 0.17 |
这就是为什么 0.04 成为大多数非金属材质的默认 F0——绝大多数非金属(塑料、木材、石材、陶瓷等覆盖的涂层或基底)的 IOR 落在 1.31.5 区间,对应的 F0 ≈ 0.020.04。
金属的 F0 为什么不同
金属的折射率是复数形式:
1 | |
其中的 k(消光系数,Extinction Coefficient) 描述了金属对光的吸收能力。这导致两个关键差异:
- F0 整体更高 — 金属的 F0 通常在 0.5~1.0 范围,远比非金属高
- F0 有颜色 — n 和 k 在不同波长下各不相同,因此金属的 F0 是光谱值,表现为有色反射
常见金属的 F0(近似 RGB 值):
| 金属 | F0(线性 RGB) | 视觉特征 |
|---|---|---|
| 铁 | (0.56, 0.57, 0.58) | 灰白色反射 |
| 金 | (1.00, 0.76, 0.33) | 黄色反射 |
| 铜 | (0.95, 0.64, 0.54) | 橙红色反射 |
| 银 | (0.97, 0.96, 0.91) | 接近白色反射 |
这就是金属的高光带有自身颜色、而非金属的高光通常接近光源颜色的根本原因。
为什么叫”基础”反射率
“基础”二字至少包含三层含义:
1. 它是反射率的基准下限
菲涅尔效应决定了反射率随视角增大只会升高,不会降低。F0 是整个反射率曲线中最低的那个点——也就是表面在”最不反射”情况下的反射率。因此它是描述材质反射行为的”基线”。
2. 它决定能量的起始分配
在能量守恒公式中:
1 | |
F0 = 0.04 意味着垂直观察时 4% 的能量直接反射(Specular),96% 进入内部产生漫反射(Diffuse)。这个比例是后续所有光照计算的基础,所以 F0 是”基础”参数。
3. 它是材质分类的依据
金属和非金属最直观的物理区别就体现在 F0 上:
| 非金属 | 金属 | |
|---|---|---|
| F0 范围 | 0.02~0.08(低) | 0.5~1.0(高) |
| F0 是否有颜色 | 无(灰度值) | 有(光谱色) |
| 视觉表现 | 高光接近光源色 | 高光带有金属色 |
在金属度工作流中,最终使用的 F0 由非金属默认值(0.04)和金属 F0 按 Metallic 插值得到:
1 | |
这也是为什么金属的 Base Color 本质上是它的 F0,而非金属的 Base Color 是漫反射颜色——两者在渲染管线中的角色不同。
4.3 G:Geometry Function
微表面会互相遮挡:
- 从光源方向看不到的微表面处于 Shadowing。
- 从相机方向看不到的微表面处于 Masking。
G 用来描述这种微观遮挡。常见实现使用 Smith 方法,并为 GGX 使用 Schlick-GGX 等近似。
注意它和场景中的 Shadow Map 不是一回事:
- Shadow Map 处理物体之间的宏观遮挡。
G处理材质表面内部的微观自遮挡。
5. 漫反射与能量守恒
最简单的漫反射模型是 Lambert:
1 | |
除以 π 是为了保证在整个半球积分后不超过输入能量。
但同一束光不能同时被完整地用于镜面反射和漫反射。先被表面反射的部分不会再进入材质内部,因此常写成:
1 | |
kS:分给镜面反射的比例。kD:分给漫反射的比例。
金属的 kD 接近 0,因为可见光进入金属后会迅速被吸收,几乎没有普通意义上的漫反射。
一些更完整的模型会使用 Burley Diffuse、多次散射能量补偿等方法,修正 Lambert 或单次散射微表面模型的不足。但理解基础 PBR 时,先掌握能量如何在 Diffuse 与 Specular 之间分配最重要。
6. 金属度工作流
游戏引擎最常见的是 Metallic-Roughness 工作流。
6.1 Base Color
Base Color 不是简单的“物体看起来是什么颜色”。
- 非金属:表示漫反射颜色,不应包含烘焙进去的灯光、高光和阴影。
- 金属:表示有色镜面反射的
F0,材质几乎没有漫反射。
Base Color 通常作为颜色纹理,以 sRGB 方式读取并在线性空间参与光照计算。
6.2 Metallic
Metallic 表示材质更接近金属还是非金属:
0:非金属,例如木材、塑料、石头。1:金属,例如铁、金、铜。
现实中纯材质通常是 0 或 1。贴图中的中间值主要用于:
- 像素覆盖了金属与非金属的交界。
- 灰尘、锈迹、涂层等混合材质。
- 纹理过滤和抗锯齿产生的过渡。
生锈的铁表面不能简单理解成“半金属”。氧化层本身通常是非金属,它只是覆盖在下面的金属上。
6.3 Roughness / Smoothness
Roughness 控制微表面朝向的分散程度:
0:光滑,反射清晰,高光集中。1:粗糙,反射模糊,高光分散。
有些引擎使用 Smoothness:
1 | |
但通道位置和内部映射未必相同。例如 glTF 的 Metallic-Roughness 纹理使用 G 通道保存 Roughness、B 通道保存 Metallic,并要求按线性数据读取。Unity 不同渲染管线和工作流的打包方式需要单独确认。
6.4 Normal、AO 和 Emission
- Normal Map:改变光照使用的局部法线,增加表面细节,但不会改变真实轮廓。
- Ambient Occlusion:描述小尺度缝隙对间接光的遮蔽,不应该粗暴乘到所有直接光上。
- Emission:表面自行发出的光。它能让材质显示得很亮,但是否照亮周围物体取决于 GI、光照贴图或额外光源。
这些纹理属于数据而不是颜色,除 Base Color、Emission 等颜色纹理外,通常应以 Linear / Non-Color 方式读取。
7. 直接光照
对于一个点光源或方向光,可以把单灯贡献简化成:
1 | |
其中:
- BRDF 决定材质如何反射光。
N · L决定表面接收到多少光。- Attenuation 表示距离和聚光角度衰减。
- Shadow 表示场景级遮挡。
不要在 BRDF 内外重复乘 N · L。公式的具体组织方式在不同代码库中会有差异,判断时要看函数返回的是完整 BRDF,还是已经包含余弦项的光照响应。
8. IBL:环境光照
真实场景的光并不只来自几个解析光源。天空、墙面和周围物体会从所有方向提供入射光。
IBL(Image Based Lighting)使用 Cubemap 或环境探针表示这些方向的光照。它通常分为两部分:
8.1 Diffuse IBL
漫反射会把入射光散射到较宽方向,因此环境贴图可以卷积成低频 Irradiance Map,或使用球谐函数保存。
1 | |
8.2 Specular IBL
镜面环境反射同时依赖法线、观察方向和粗糙度。如果运行时对整个半球完整积分,成本会很高,因此通常进行 Split-Sum 近似:
- 把环境 Cubemap 按不同粗糙度预过滤到不同 Mip。
- 用预积分 BRDF LUT 保存 Fresnel 和几何项的组合结果。
1 | |
粗糙度越高,采样越模糊的 Mip。Reflection Probe、天空盒预过滤和 BRDF LUT 共同构成了常见的实时镜面 IBL。
这仍然是近似:探针通常不知道真实遮挡和物体在场景中的准确位置,因此会出现漏光、反射漂浮或物体无法正确出现在反射中的问题。
9. Tone Mapping 与颜色空间
PBR 光照结果通常是 HDR,可以大于 1。要显示到普通屏幕,还需要曝光和 Tone Mapping 把高动态范围映射到显示范围。
1 | |
Tone Mapping 不属于 BRDF,但它会强烈影响我们最终看到的高光、对比度和颜色。相同材质在不同引擎中看起来不同,可能不是 PBR 参数错了,而是环境光、曝光、Tone Mapping 和颜色管理不同。
10. Unity 中的对应关系
以 Unity 常见 Lit 材质为例:
- Base Map / Base Color:材质基础颜色。
- Metallic:金属度。
- Smoothness:通常与 Roughness 相反。
- Normal Map:切线空间法线。
- Occlusion:间接光遮蔽。
- Emission:自发光。
- Main Light / Additional Lights:直接光。
- Reflection Probe / Environment Reflections:镜面 IBL。
- Light Probe / Lightmap / SH:漫反射间接光。
Built-in、URP、HDRP 的 BRDF、贴图打包和能量补偿实现并不完全一致。写自定义 Shader 时,最好复用当前渲染管线提供的光照函数,并阅读对应版本源码,而不是把一份网上的 Cook-Torrance 公式直接复制进来就认为完成了 PBR。
11. 常见错误
- 把金属度当成高光强度。 金属度改变的是材质类别和能量分配。
- 在 Base Color 中画入高光和阴影。 光照改变后,这些信息仍然黏在材质上。
- 用纯黑金属。 金属的可见颜色主要来自有色镜面反射,过暗的 Base Color 会让它几乎无法反光。
- 随意使用 0 到 1 的半金属值。 大多数纯表面应接近 0 或 1。
- 把 Roughness 当成 Specular 强度。 它主要控制反射分布宽度。
- 把数据贴图按 sRGB 读取。 Metallic、Roughness、Normal、AO 通常应使用线性采样。
- 只调材质,不检查环境。 没有合理的 HDR 环境与曝光,再正确的金属也可能像灰塑料。
- 把 AO 乘到所有光照。 AO 主要用于削弱间接光;直接光遮挡应由阴影等机制决定。
- 法线贴图强度过大。 它会破坏宏观法线与微表面粗糙度之间的合理关系,并产生闪烁。
12. 总结
PBR 的知识链可以压缩为:
1 | |
最需要记住的不是某一条公式,而是四个约束:
- 粗糙度描述微表面分布。
- 菲涅尔决定反射随角度变化。
- 金属与非金属的漫反射和
F0不同。 - 漫反射与镜面反射必须共享有限的入射能量。
在这个基础上,再去理解 Clear Coat、Sheen、Anisotropy、Subsurface、Transmission 等扩展材质,就不会只是堆参数,而是在基础 BRDF 上增加新的光学层次。