Substrate 材质学习记录
2026/8/27 18:31:08 网站建设 项目流程

BSDF包括了BRDF 和 BTDF

简而言之,BRDF是反射,BTDF是投射

透射的本质是光穿过不同的介质

在引擎里面经常看到BXDF,其实BXDF里的x是占位符

这里的x可以替换成:

R:Reflectance T:Transmittance S:Scattering

光射到物体表面都会有三层

1. Specular / F0 表面镜面反射,也就是光刚碰到表面时,有多少被直接反射回来。 2. BaseColor / Albedo 非金属时,进入表层后的光被吸收一部分,再以漫反射形式出来的颜色。 金属时,BaseColor 更多影响镜面反射颜色。 3. Transmission / Subsurface / Mean Free Path 光真的进入介质内部,走了一段距离,被吸收、散射、透射出来。

自由程更准确叫:

Mean Free Path 平均自由程

它描述的是:

光在介质内部平均走多远会发生一次散射/吸收

学习substrate前,我们先了解一下substrate里面的术语

这几个是 Substrate 的骨架。

概念重要程度为什么要先懂
BSDF必须Substrate 的材质本质就是一堆 BSDF。
closure必须一个可被材质树管理的 BSDF 单元。你要知道 ClosureCount 数的是它。
lobe必须一个 closure 内部的具体光照分量,比如 diffuse/specular/fuzz。
material tree必须多个 BSDF 怎么 mix / over / layer,靠树结构表达。
feature mask必须材质用了哪些特殊能力,比如 SSS、Fuzz、Anisotropy、Toon。
simplification必须Substrate 很复杂,很多路径会强制简化。这个不懂,调 Lumen/RT 会懵。
fully-simplified projection必须Lumen card、RT、MaterialCache 等经常不吃完整材质,而吃简化投影。

substrate里面的closure是什么?

先举最简单例子:普通塑料球

一个普通红色塑料球:

红色塑料

它虽然里面有很多参数:

颜色 粗糙度 金属度 高光 法线

但它整体就是一种材质。

所以可以理解成:

Closure 0 = 红色塑料

也就是:

ClosureCount = 1

不是因为它只有一个参数,而是因为它只有一个“材质单元”。

问:那我以车漆举例子,散粉,车漆,还有保护层,三层就是三个closure,然后closurecount = 3?

答:对,可以先这么理解:

散粉层 + 车漆层 + 保护层 ≈ 3 个材质层 ≈ 3 个 closure ≈ ClosureCount = 3

这个理解方向是对的。

不过要补一个小心点:在 UE Substrate 真实编译/运行里,不一定永远严格等于 3。因为引擎可能会做合并、简化、裁剪、质量降级。但概念上,你这样理解完全没问题。


什么是lobe

lobe就是:

一个 closure 里面的某一种反光/散射分量。

更白话:

closure 是一个完整材质包; lobe 是这个材质包里的一个光照效果分支。

你有一个车漆 closure:

Closure:红色车漆

这个红色车漆受到光照后,不只产生一种效果。

它可能同时有:

1. 红色漫反射 2. 镜面高光 3. 金属颗粒高光

这些不同的“光照分量”,就可以理解成不同 lobe。

比如:

Closure:红色车漆 ├─ Lobe 0:Diffuse 漫反射 ├─ Lobe 1:Specular 镜面反射 └─ Lobe 2:Metal flakes 金属颗粒反射

什么是material tree?

你有三层:

散粉 保护层 车漆

如果只是单独列出来,还不够。

Substrate 还需要知道它们的关系:

散粉 是覆盖在保护层上? 保护层 是覆盖在车漆上? 散粉和保护层是混合? 还是按 mask 混合?

所以它会形成一棵树。

比如:

Over / \ 散粉 Over / \ 保护层 车漆

这就是 material tree。

意思是:

散粉 over 保护层 over 车漆

什么是feature mask

节点面板上“有这个输入口” 不等于 feature mask 一定打开。

feature mask 更关心:

这个材质最终是否真的用了这个 feature。

什么是simplification

simplification就是:

把复杂 Substrate 材质压成一个更简单、便宜、兼容性更好的近似材质。

换句话说:

完整材质太贵/太复杂/某些渲染路径吃不下, 引擎就把它“折叠”成一个简化版本来用。

先用你的车漆例子

完整车漆可能是:

散粉层 over 透明保护层 over 红色车漆层 + 金属颗粒 + Fuzz + Anisotropy

这可能有:

多个 closure 多个 lobe 复杂 material tree 特殊 feature

在主视角 raster direct lighting 里,也许还能认真算。

但到了某些路径,比如:

Lumen Card Capture Ray Tracing Material Cache 某些 Path Tracing 辅助路径 远处 HLOD

它可能不想/不能完整处理这么复杂。

于是就 simplification:

复杂车漆 ↓ 简化成一个普通近似材质

比如:

BaseColor ≈ 混合后的红色 Roughness ≈ 一个平均粗糙度 F0 ≈ 一个近似反射率 Normal ≈ 主法线 Emissive ≈ 近似发光

原来多层结构可能被压成:

一个 Slab BSDF

一个 Slab BSDF 通常就是一个 closure。


什么是fully-simplified projection?

fully-simplified projection可以理解成:

把一个复杂 Substrate 材质,投影/压缩成一份最简单、最通用、所有路径都能读懂的材质结果。

如果simplification是“简化”,那fully-simplified projection就是:

简化到最彻底的版本。

先用车漆例子

你的完整车漆:

散粉层 over 保护清漆层 over 红色车漆层 + 金属颗粒 + Fuzz + Anisotropy

完整 Substrate 里可能有:

多个 closure 多个 lobe 复杂 material tree 特殊 feature mask

但是某些路径,比如:

Lumen Card Material Cache 部分 Ray Tracing 部分 Path Tracing 辅助路径 GPU Lightmass 旧 GBuffer fallback

可能不想处理这么复杂。

于是它需要一份“最低保真但稳定通用”的版本:

一个近似 BaseColor 一个近似 Roughness 一个近似 F0 / Specular 一个近似 Normal 一个近似 Emissive

这就是 fully-simplified projection。


顺序:

1、先想光打到物体表面, 反射多少,反射率又是多少,然后填写F0,其中F就是fresnel的意思

2、思考光打到物体表面后会不会射入物体,如果不射物体,Diffuse Albedo和SSS MFP就不用考虑了

3、如果会打入物体内部思考光打入物体内部的固有色是什么颜色Diffuse Albedo

4、然后再考虑光线能在物体能不射多深,设置SSS MFP

入射光 ↓ ┌──────────────────── 表面薄薄一层 ────────────────────┐ │ │ │ 一部分光直接弹走 → Specular 高光 → F0 控制颜色/强度 │ │ │ └───────────────────────────────────────────────────────┘ ↓ 剩下的光进入里面 ↓ ┌──────────────────── 材质内部 / 底层 ──────────────────┐ │ │ │ 光被吸收、散射,再出来 → Diffuse → DiffuseAlbedo 控制颜色 │ │ │ └───────────────────────────────────────────────────────┘

拿红色塑料举例:

红色塑料 F0: 很低,偏灰白 只影响高光 Diffuse Albedo: 红色 决定物体大面积主体颜色 最终看起来: 红色身体 + 灰白/白色高光

画成这样:

白色小高光 ↓ ┌────────────────┐ │ ◯ │ ← F0 负责这个高光颜色 │ │ │ 红红红红红 │ ← DiffuseAlbedo 负责大面积红色 │ 红红红红红 │ └────────────────┘

材质里的SSS通常代表Subsurface Scattering,中文叫次表面散射

意思是:光线不是只在物体表面反射,而是会进入材质内部,经过散射后再从附近透出来。

入射光首先根据菲涅耳效应在表面产生镜面反射,其中正视角下的基础反射率由F0决定;未被表面反射的光进入材质内部,并在吸收与散射作用下传播,其传播深度和扩散范围由mfp等参数控制。经过多次散射后,部分光从入射点附近重新出射,形成 SSS 效果,其最终颜色和强度受到DA(漫反射颜色)、次表面颜色以及吸收参数的共同影响。

“进入皮肤内部并在内部改变方向”叫散射;
“经过散射后又从皮肤表面附近出来”叫次表面散射(SSS)的完整结果。

参考视频,讲的很清晰:https://www.bilibili.com/video/BV1bx411s775/?spm_id_from=333.337.search-card.all.click

概念含义视觉结果
透射 Transmittance光从材质一侧进入,穿过材质后还有多少能出来透明、半透明、带颜色的透光
散射 Scattering / SSS光进入材质后,在内部被多次改变方向发软、发雾、边缘透光、皮肤/蜡/玉/牛奶感

MFP是光在材质内部两次散射之间的平均传播距离,不是一个固定的几何深度。

但不要把它理解成“光固定进入 2 cm 深度后才出来”。它是一个平均传播距离,实际路径会因为多次散射而改变。

各向异性可以概括为:

材质的光照、反射或散射效果会随着方向不同而不同。

表面各向异性 → 表面反射的高光沿发丝方向拉长 → 主要形成头发上的细长亮带 SSS 内部散射各向异性 → 光进入发丝内部后,散射更偏向某个方向 → 影响内部光的传播和重新出射

对应你 UE 的节点参数:

  • Anisotropy:主要控制表面高光的方向性;
  • SSS Phase Anisotropy:控制 SSS 内部散射的方向性。

单根发丝:沿长度方向法线变化很小 入射光 ↘ ↘ ↘ ↘ ↓n ↓n ↓n ↓n 反射到摄像机 ═══════════════════════ ↗ ↗ ↗ ↗ ──────── 细长高光 ─────── ←── 发丝长度方向 ──→ 沿发丝长度方向,表面法线变化很小, 相同的反射条件会重复出现, 所以高光会连成一条长亮带。

各向异性正值沿Tangent拉长高光,负值沿Tangent的垂直方向拉长

左边:

微小镜面朝向杂乱 → 反射方向分散 → 形成圆形高光

右边:

微小镜面结构沿发丝方向排列 → 反射光方向更集中、更有方向性 → 高光沿发丝方向拉长

最重要的一句话是:

各向异性不是让光沿着发丝跑,而是让发丝表面的许多微小镜面,把光反射成沿发丝方向排列的亮带。


Substrate 材质中 Diffuse Albedo、F0 与光源颜色之间的物理耦合关系:当材质主要反射绿色漫反射和蓝色镜面光,而场景只提供红色入射光时,材质表面会因缺少可反射能量而显著变暗,从而体现 Substrate 对界面反射、介质散射和能量守恒的表达能力。

在UE5.8的新shadingmodels下面有多出来两个新的shadingmodel:

TranslucentGreyTransmittanceSubstrate 下的普通半透明,透过率是灰度/单通道普通透明玻璃、薄雾、简单半透明

TranslucentColoredTransmittanceSubstrate 彩色透射半透明,类似旧 ThinTranslucent彩色薄玻璃、有色透明材质

Sub-Surface Type 下拉

枚举它做什么光的“方向感”适合什么
None不启用次表面散射没有皮下透光/扩散金属、普通不透明材质
Wrap用很便宜的方式模拟皮肤/蜡质的“绕光”光会从亮面稍微包到暗面,柔化明暗交界二次元皮肤、卡通柔边、低成本 SSS
Two-Sided WrapWrap 的双面版本背面的光也能影响正面,像薄片被光穿过树叶、耳朵、薄布、纸片
Diffusion更真实的皮下扩散光进入表面后,在皮下横向扩散,再从附近出来皮肤、蜡、玉、需要柔和肉感的材质
Diffusion Profile用 Subsurface Profile 资产控制扩散和 Diffusion 类似,但扩散颜色/半径由 Profile 控制UE 传统皮肤 SSS 工作流
Simple Volume简单体积透光光沿厚度/视线穿过材质,像薄玻璃或透明体薄玻璃、半透明体、带颜色透射的材质

UE5 Path Tracing 本质上是:从玩家屏幕/摄像机视角往场景里发出很多条随机光路,模拟它们在场景里反射、折射、散射、吸收,最后把大量样本平均成一张图。

一条路径大概这样:

相机 ↓ 打到模型表面 ↓ 根据材质 BSDF 决定:反射?折射?进入内部?漫反射? ↓ 继续打到下一个表面 ↓ 再根据那个材质继续弹射 ↓ 最后命中光源 / 天空 / 环境光 ↓ 得到这个像素的一次采样颜色

实时渲染里的Temporal通常是:

上一帧 + 当前帧 → 做抗锯齿、降噪、稳定画面 → 目标是实时显示

Path Tracing / Movie Render Queue 里的Temporal Samples更像是:

在一个快门时间内,采样多个时间点 → 用来得到更准确的运动模糊、景深、动画中的采样 → 每个时间点也会做 Path Tracing 采样

也就是说:

Spatial Samples = 同一帧、同一时间点,对像素多采几次。 Temporal Samples = 同一帧的快门时间内,取多个时间点采样。

最终样本数大概是:

总样本数 = Spatial Samples × Temporal Samples

一帧画面并不一定代表“某一个瞬间”,它可以代表“一小段时间内看到的平均结果”。

这就是相机里的“快门时间”。

比如一秒 24 帧:

第 10 帧 不是只能表示 0.416666 秒这个瞬间 它也可以表示: 0.416 秒 ~ 0.458 秒 这段时间里相机接收到的平均光
这一帧不是只算一个时间点 而是在快门时间内取 8 个时间点 t1:算一次 t2:算一次 t3:算一次 ... t8:算一次 最后平均成这一帧

Path Tracing 的关键恰恰是:从相机出来的路径,大多数时候是在随机试探,最后不一定能命中光源。

一条路径大概是:

相机射线 ↓ 打到表面 ↓ 根据材质随机选一个下一跳方向 ↓ 再打到别的表面 ↓ 继续随机弹 ↓ 可能命中光源,也可能一直没找到光源

如果最后命中光源:

这条样本有贡献

如果没有命中光源:

这条样本贡献很小,甚至是黑的

然后它靠大量采样平均:

有些路径找到光 有些路径没找到光 平均之后 = 这个像素实际接收到的光照概率

但 UE / 现代 Path Tracer 不会只靠“瞎弹到光源”。

因为那样很慢,尤其是小灯。通常会做一件事:

每次打到一个表面时 额外朝光源方向发一条“阴影/可见性测试射线”

也就是:

相机 → 表面点 ↓ 直接连到光源检查一下

如果中间没被挡住,就把这个光源的直接照明算进去。

所以更准确的结构是:

相机射线打到表面后,会做两件事: 1. 直接光采样 → 主动问:这个点能不能看到某个光源? 2. 间接光路径继续弹射 → 随机选方向,继续找下一次反射/折射/散射

因此不是一开始就知道“这条线会射回光源”。

而是:

先从相机找到可见点,再在每个可见点上,一边主动采样光源,一边继续随机追踪间接光。

金属度转 Diffuse Albedo / F0

传统 UE 材质里常用:

Base Color Metallic Specular Roughness

但 Substrate 更偏物理拆分:

Diffuse Albedo:介质/漫反射颜色 F0:正面视角的基础镜面反射 F90:掠射角的镜面反射颜色

所以Substrate Metalness-To-DiffuseAlbedo-F0节点的作用就是:

把旧 PBR 的 BaseColor / Specular / Metallic 转换成 Substrate 需要的 Diffuse Albedo / F0

核心理解:

非金属 Metallic = 0: BaseColor 主要进入 Diffuse Albedo F0 保持较低,通常是塑料/皮肤/石头那种小高光 金属 Metallic = 1: Diffuse Albedo 基本没了 BaseColor 更多变成有颜色的 F0 因为金属主要靠表面镜面反射显色

二次粗糙是什么
讲的是Second RoughnessSubstrate Haziness-To-Secondary-Roughness

你可以把普通粗糙度想成:

一个高光波瓣

二次粗糙就是:

再加一个高光波瓣

也就是一个材质可以同时有:

主高光:比较清晰、比较集中 次高光:更宽、更散、更像雾感/浑浊感

所以它不是 SSS,也不是 MFP。它仍然主要是表面镜面反射的形状变化。

直观效果:

只有 Roughness: 一个高光,干净直接 Roughness + Second Roughness: 一个亮核心 + 一圈更软的泛光/浑浊高光

Haziness-To-Secondary-Roughness就是把“浑浊感”转成合理的二次粗糙度。官方也把它列为 Substrate Helper Node,用来根据基础粗糙度和 haziness 计算第二个高光波瓣粗糙度。

油膜专项
是在用“油膜”这个例子讲 Substrate 辅助节点的用途。

油膜不要理解成普通颜色贴图。它更像:

表面覆盖了一层极薄透明膜 光在薄膜上表面和下表面发生反射 不同波长互相增强/抵消 于是产生彩色高光

所以油膜颜色主要来自:

镜面反射 / 视角变化 / 薄膜干涉

不是来自:

Diffuse Albedo 漫反射颜色

这点很关键。油膜、肥皂泡、金属氧化膜那种彩虹色,本质上更接近薄膜高光颜色变化,不是“材质内部散射出来的颜色”。

Thin-Film、F0、F90、Normal、IOR
Substrate Thin-Film节点。官方 API 里这个节点的输入包括:

F0 F90 IOR Normal Thickness

它的作用是:

根据薄膜参数,重新计算材质的镜面 F0 / F90 表现

各参数可以这样理解:

F0: 正面看材质时的基础高光反射。 F90: 侧面、掠射角看材质时的高光颜色。 IOR: 薄膜折射率,影响光进入薄膜后的弯折和反射比例。 Normal: 决定局部表面朝向。法线变了,入射角也变,薄膜颜色也会变。 Thickness: 薄膜厚度。厚度变化会导致不同颜色被增强/抵消,所以会出现彩虹油膜感。

Blend Mode 混合模式:

选项含义常见用途
Opaque完全不透明,不透光角色身体、衣服、武器、石头、金属、绝大多数材质
Masked二值裁剪,要么显示,要么不显示树叶、头发卡片、破洞布料、铁丝网
TranslucentGreyTransmittance半透明,但透射颜色被简化成灰度,性能更好普通玻璃、水膜、轻透明材质,实时更推荐
TranslucentColoredTransmittance完整彩色透射,光穿过材质会被染色彩色玻璃、液体、宝石、厚水层,更贵
ColoredTransmittanceOnly只保留透射/吸收效果,表面反射交互基本为 0类似滤色片、纯吸收介质、特殊玻璃透色测试
Additive材质颜色加到背景上,越叠越亮火焰、能量、魔法、粒子、光晕
AlphaComposite预乘 Alpha 混合,比普通透明更适合烟雾/粒子边缘烟、雾、火焰、半透明 VFX
AlphaHoldout用当前材质把后面的透明物体“挖洞”特殊遮罩、UI/VFX 合成,很少用于普通材质

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询