UE5.8 Substrate Glint 笔记

UE5.8 Substrate Glint 笔记

1. Glint 是什么

Glint 用于表现大量稀疏、细小、明亮的微表面闪点。

适合:

  • 金属粉末
  • 珠光漆
  • 钻石或宝石闪烁
  • 细小晶体
  • 湿润颗粒
  • 闪粉、亮片

普通 GGX 高光会把大量微小高光平均成一个连续高光,无法表现真实的颗粒闪烁。Glint 保留了这些离散的微晶体高亮事件。


2. Glint 和普通高光的区别

普通 GGX:

复制代码
整个像素使用一个连续的微表面分布

Glint:

复制代码
一个像素覆盖多个微晶体 Cell
每个 Cell 拥有独立的随机微表面状态
分别评估后再过滤合成

因此 Glint 的亮度会随着以下因素变化:

  • 摄像机移动
  • 光源方向变化
  • 物体旋转
  • UV 变化
  • 微晶体密度变化
  • 微表面粗糙度变化

3. 微表面斜率是什么

微表面不是完全平的,每个微表面都有自己的倾斜方向。

用两个数表示微表面倾斜程度:

复制代码
slope = (sx, sy)

例如:

复制代码
(sx, sy) = (0, 0)       表示平面
(sx, sy) = (0.3, 0)     向 X 方向倾斜
(sx, sy) = (0, -0.2)    向 Y 负方向倾斜

根据光线方向 L 和视线方向 V,先计算半角向量:

复制代码
H = normalize(L + V);

然后把半角向量转换成目标斜率:

复制代码
slope_h = float2(
    -H.x / H.z,
    -H.y / H.z
);

这个目标斜率表示:

微表面需要倾斜成什么样,才能把光反射到摄像机。

假设两个目标半角方向拥有相同的 NoH:

复制代码
目标 A:H = (0.6, 0.0, 0.8)
目标 B:H = (0.0, 0.6, 0.8)

两者都有:

复制代码
NoH = 0.8

如果你只使用:

复制代码
D(NoH)

那么 A 和 B 的微表面概率一定相同。

但它们的斜率分别是:

复制代码
Slope A = (-0.75,  0.0)
Slope B = ( 0.0, -0.75)

现在假设材质中有一种方向性微晶体分布:

复制代码
X 方向容易出现长条微晶体
Y 方向几乎没有微晶体

那么真实结果应该是:

复制代码
P22(Slope A) 很高
P22(Slope B) 很低

但 NoH 无法区分它们,因为两者的 NoH 都是 0.8。

这就是斜率的实际好处:

复制代码
NoH 只能表达"距离中心多远"
Slope 还能表达"具体朝哪个方向"

4. P22 是什么

P22 可以理解为微表面斜率的概率分布。

它回答的问题是:

当前材质中,有多少微表面拥有这个倾斜方向?

如果目标斜率在分布中很常见:

复制代码
P22 较高
→ 高光较强

如果目标斜率很罕见:

复制代码
P22 较低
→ 高光较弱

Glint 中的 P22_M 是针对某个具体 Cell 的局部斜率分布评估。


5. Beckmann 在 Glint 中的作用

UE5.8 Glint 使用 Beckmann 形式的微表面斜率分布。

源码中会根据粗糙度创建 Beckmann 描述:

复制代码
FBeckmannDesc Beckmann = GGXToBeckmann(SafeRoughness);

粗糙度较低:

复制代码
微表面方向集中
高光更尖锐

粗糙度较高:

复制代码
微表面方向分散
高光更宽、更柔和

Glint 并不是简单读取一张噪声贴图,而是根据目标斜率评估微表面匹配概率。


6. Glint 的完整处理流程

复制代码
Glint UV
   ↓
计算 UVDDX / UVDDY
   ↓
构建当前像素 footprint
   ↓
把 footprint 近似成椭圆
   ↓
计算 major / minor 轴
   ↓
根据 minorLength 选择 LOD
   ↓
遍历椭圆包围盒中的候选 Cell
   ↓
计算每个 Cell 的 P22_M
   ↓
根据椭圆距离计算 EWA 权重
   ↓
对所有 Cell 加权累积
   ↓
sum / sumWts 归一化
   ↓
相邻 LOD 插值
   ↓
输出 Glint_D
   ↓
进入 Substrate 的光照计算

7. Footprint 是什么

Footprint 表示:

当前屏幕像素在 Glint UV 空间中覆盖的区域。

由于一个屏幕像素通常不只对应一个 UV 点,而是覆盖一小片 UV 区域,所以不能只采样一个微晶体。

通过 UV 导数得到 footprint:

复制代码
UVDDX = ddx(GlintUV);
UVDDY = ddy(GlintUV);

这两个导数描述:

  • 屏幕像素向 X 方向移动时,UV 如何变化;
  • 屏幕像素向 Y 方向移动时,UV 如何变化。

它们形成一个 UV 平行四边形,Glint 将其进一步近似为椭圆。


8. 为什么要用椭圆 footprint

椭圆可以表示:

  • footprint 的长轴;
  • footprint 的短轴;
  • footprint 的旋转方向;
  • 当前像素覆盖的微晶体范围。

Glint 会计算:

复制代码
majorLength
minorLength
eccentricity

并限制最大各向异性,源码中使用:

复制代码
MaxAnisotropy = 4

这样可以避免极端拉伸的 footprint 导致性能和稳定性问题。


9. LOD 的作用

根据 footprint 的大小选择微晶体分布的 LOD。

源码逻辑大致是:

复制代码
l = NLevels - 1 + log2(minorLength);
il = floor(l);
w = frac(l);

得到:

复制代码
il       当前 LOD
il + 1   相邻 LOD
w        两个 LOD 的插值权重

最后进行:

复制代码
P22 = lerp(P22_il, P22_il_plus_1, w);

LOD 的作用:

  • footprint 很小时使用更细的微晶体分布;
  • footprint 很大时使用更粗的统计分布;
  • 避免远处闪点过密;
  • 减少远距离闪烁;
  • 减少 LOD 切换跳变。

10. Cell 遍历

Glint 不会遍历无限范围,而是先计算椭圆的包围盒。

对于包围盒内的每个候选 Cell,计算它相对于椭圆中心的位置:

复制代码
ss = Cell 局部坐标 X
tt = Cell 局部坐标 Y

然后计算椭圆距离:

复制代码
r2 = A * ss * ss
   + B * ss * tt
   + C * tt * tt;

判断:

复制代码
r2 < 1

只有在椭圆 footprint 内的 Cell 才参与计算。

椭圆外的 Cell 会被直接跳过。


11. P22_M 的处理内容

每个候选 Cell 会进行局部微晶体评估,主要包括:

  1. 稳定哈希;
  2. 随机序列生成;
  3. 随机旋转;
  4. 微晶体相对面积判断;
  5. LOD 对应的微晶体密度;
  6. 目标斜率计算;
  7. Beckmann 斜率分布评估;
  8. Glint LUT 查询;
  9. 返回该 Cell 的局部响应。

可以概括为:

复制代码
P22_M =
    微晶体密度
    × 斜率匹配概率
    × 随机微晶体状态

12. EWA 权重

Glint 使用椭圆加权思想,对 footprint 内的 Cell 进行空间过滤。

源码中的权重大致为:

复制代码
W = exp(-2 * r2) - exp(-2);

权重特点:

复制代码
r2 越小 → 越接近椭圆中心 → 权重越大
r2 越接近 1 → 越接近边缘 → 权重越小
r2 ≥ 1 → 不参与计算

累积过程:

复制代码
sum += P22_M * W;
sumWts += W;

最后归一化:

复制代码
filtered = sum / max(epsilon, sumWts);

这样可以把一个像素覆盖的多个闪点合成为稳定结果。


13. Glint 为什么不会简单地闪烁失控

Glint 不是简单地给每个像素生成随机噪声,也不是简单叠加上一帧结果。

它主要依靠:

  • 稳定哈希;
  • UV footprint;
  • 椭圆 Cell 过滤;
  • EWA 权重;
  • LOD 选择;
  • 相邻 LOD 插值;
  • 微表面斜率分布。

因此它属于:

复制代码
当前像素空间范围内的统计过滤

而不是:

复制代码
上一帧画面累积

14. Glint 的主要性能开销

Glint 比普通 GGX 贵,原因不是单独的 NoH 或一次法线匹配,而是多个步骤叠加:

  1. 计算 UV 导数;
  2. 构建 footprint;
  3. 计算椭圆包围盒;
  4. 遍历多个候选 Cell;
  5. 每个 Cell 执行哈希和随机化;
  6. 计算微晶体斜率;
  7. 查询 Glint LUT;
  8. 计算 EWA 权重;
  9. 对两个相邻 LOD 分布进行评估;
  10. 归一化并进行最终插值。

简化表示:

复制代码
Glint 成本
≈ Cell 数量
× 每个 Cell 的斜率分布计算
× LOD 数量
× LUT / SampleGrad 成本

footprint 越大,候选 Cell 越多,成本越高。


15. Glint 的性能控制方向

可以从以下方面控制成本:

  • 降低 Glint Density;
  • 降低 Glint 覆盖范围;
  • 限制最大各向异性;
  • 远距离降低 Glint 强度;
  • 远距离使用更粗 LOD;
  • 只对重要材质启用;
  • 使用平台质量开关;
  • 避免在大量屏幕像素上同时使用;
  • 避免和高成本透明、折射、复杂 Substrate lobe 叠加。

Glint 适合用于:

复制代码
少量高价值材质

不适合默认应用到整个场景。


16. Glint 和 Fuzz 的区别

Glint

复制代码
稀疏、离散、闪烁的微晶体高光

适合:

  • 金属闪粉;
  • 宝石;
  • 珠光漆;
  • 水晶;
  • 亮片;
  • 微小晶体。

Fuzz

复制代码
连续、柔和、掠射角明显的高光 lobe

适合:

  • 短绒;
  • 毛发边缘;
  • 天鹅绒;
  • 布料;
  • 纤维表面;
  • 柔软织物。

核心区别:

复制代码
Glint:离散的闪点事件
Fuzz:连续的掠射反射 lobe

17. 普通 Noise 能不能替代 Glint

可以做出类似的视觉效果,但不能完全替代 Glint。

普通 Noise 叠加高光通常缺少:

  • 微表面斜率匹配;
  • 真实的半角方向响应;
  • footprint 过滤;
  • Cell 级别的随机微晶体;
  • LOD 统计;
  • EWA 空间积分;
  • 稳定的远距离表现。

所以普通 Noise 更像:

复制代码
颜色噪声 + 人工亮度权重

Glint 更像:

复制代码
微晶体分布 + 光学方向匹配 + 空间过滤

18. 最终理解

Glint 的核心不是"生成很多随机亮点",而是:

复制代码
根据光线和视线计算目标微表面斜率
↓
判断每个微晶体是否拥有接近这个斜率
↓
根据当前像素 footprint 过滤多个微晶体
↓
使用 EWA 权重和 LOD 插值合成最终高光

最简公式:

复制代码
GlintPixel
≈
Σ(
    P22_M(目标斜率)
    × 微晶体密度
    × EWA footprint 权重
)
÷
Σ(EWA 权重)

一句话总结:

Glint 是对离散微晶体斜率分布进行 footprint 感知的空间过滤,从而得到稳定、稀疏、随视角变化的闪烁高光。

相关推荐
用户140360581938344 分钟前
Phase A · Step 3:模型导出 ONNX
笔记
胡二拉二胡1 小时前
抗遗忘单词表 App:让单词记忆不再「背了就忘」
经验分享·笔记·学习
2301_789380491 小时前
【踩坑记录】Windows资源管理器无限重启,改注册表、看日志
windows·经验分享·笔记
by209991 小时前
学会使用 std::string 类,并理解其内部是如何管理字符串的详细阐述(下)
c++·经验分享·笔记·字符串·类和对象·string
DevNo1 小时前
我的2026中医执业医师笔试资料使用小记
笔记·学习·考研
一隅论数智2 小时前
给AI Agent一颗“私域大脑“:本体增强的工程化之路
大数据·运维·数据仓库·人工智能·笔记·学习·政务
zhangrelay2 小时前
ubuntu图形化和命令行查看硬件参数方式汇总-Surface Go
linux·笔记·学习·ubuntu
栈溢出了3 小时前
VS Code Python 自动导包失效排查笔记
开发语言·笔记·python
yi0113 小时前
DAY19: LeetCode 28 找出字符串中第一个匹配项的下标
人工智能·笔记·python·算法·leetcode