材质系统
Material System
UE 材质 (Material) 是用节点图描述「表面如何与光交互」的着色器生成器。它有三个正交维度:着色模型 (Shading Model) 决定光照模型(Default Lit、次表面、清漆、毛发等),混合模式 (Blend Mode) 决定与背景的合成公式(Opaque/Masked/Translucent…),参数 + 材质实例 (Material Instance) 让美术在不重编译着色器的前提下做变体。PBR 输入(Base Color/Roughness/Metallic/Specular)直接对应 RTR4 的金属度-粗糙度工作流;最大的工程坑是静态参数导致的着色器排列爆炸。
材质是什么
官方定义:材质 (Material) 定义场景中物体的表面属性,可理解为涂在网格上的「颜料」;更技术地说,它告诉渲染器表面如何与光交互——颜色、反射、凹凸、透明度等,数据来自纹理和基于节点的材质表达式 (Material Expression),以及材质自身的属性设置。(Materials (landing))
从图形学角度看,材质图 (Material Graph) 本质上是一个可视化的着色器生成器:节点是 HLSL 片段的可视化,Apply 时先被翻译成 HLSL 再编译成 GPU 字节码,所以「改图 = 重编译着色器」。(Essential Material Concepts、Materials (landing))翻译管线、MaterialTemplate.ush、常量折叠与 LocalN 见 材质图到 HLSL 的翻译;需要手写 HLSL 时用 Custom 材质表达式(会阻止常量折叠)。这与 着色频率与材质系统 的「材质模板 → 着色器变体」同一问题。材质函数 (Material Function) 把一段图打包成可复用节点,分层材质 (Layered Materials) 用于组合复杂表面;UE 5.x 另有 Substrate 材质框架作为单独主题。(Materials (landing)、Essential Material Concepts)
三个正交的选择:着色模型 × 混合模式 × 参数
flowchart LR G["材质图 节点网络"] --> SM["着色模型 Shading Model 光如何反射"] G --> BM["混合模式 Blend Mode 与背景如何合成"] G --> P["参数 Parameters"] --> MI["材质实例 MIC / MID"]
PBR 输入与 RTR4 理论的对应
UE 的 PBR 输入是 Base Color、Roughness、Metallic、Specular,取值都在 0–1;官方引用 Karis《Real Shading in Unreal Engine 4》、Burley(Disney)等文献。(Physically Based Materials)它们与 基于物理的着色 和 双向反射分布函数 中金属度/粗糙度工作流一一对应:
| UE 输入 | 官方规则 | 理论对应 |
|---|---|---|
| Base Color | 偏振滤镜下拍到的颜色;非金属如木炭 0.02、新雪 0.81 | 非金属为漫反射反照率,金属为 |
| Roughness | 0 镜面、1 哑光;表面变化应放在粗糙度贴图 | 微表面法线分布宽度 |
| Metallic | 纯材质只用 0 或 1,锈蚀灰尘等混合表面才用中间值;遮罩应黑白分明 | 导体/电介质切换 |
| Specular | 默认 0.5 ≈ 4% 镜面反射,适用于绝大多数材质;不要为了“很漫反射”设为 0,应提高粗糙度 | 电介质 (由 IOR 决定) |
官方给出的 Specular 0.5 对应约 4% 反射,正是常见电介质 (,公式为通识)。Cavity 贴图用法:,,用于补法线贴图里实时阴影捕捉不到的微小遮蔽。(Physically Based Materials)纹理采样本身见 纹理映射管线。
着色模型 (Shading Models)
着色模型决定输入数据如何组合出最终外观。(Shading Models)
| 着色模型 | 用途 / 要点 | 对应理论页 |
|---|---|---|
| Unlit | 只输出自发光;本身不照亮场景,除非开启 Lumen 或 Lightmass 的自发光静态光照 | Lumen 全局光照与反射 |
| Default Lit | 默认,直接+间接光照与高光 | 基于物理的着色 |
| Subsurface / Preintegrated Skin / Subsurface Profile | 次表面散射;预积分皮肤更便宜、精度略低;Subsurface Profile 是最高质量皮肤 | 实时次表面散射 |
| Clear Coat | 标准材质上覆一层透明薄膜(车漆、易拉罐),可选双法线 | 薄膜干涉与分层材质 |
| Two Sided Foliage | 薄表面透光(树叶);Default Lit 叶片背面会发黑 | — |
| Hair / Cloth / Eye | 多重高光 / 绒毛层 / 虹膜控制;Eye 官方建议直接用 Digital Humans 的眼睛材质 | 毛发渲染、布料着色 |
| Single Layer Water | 用 Opaque 混合模式做透明水面,比半透明便宜 | — |
| Thin Translucent | 单 pass 物理正确的有色玻璃 | 透明渲染与 Alpha 混合 |
| From Material Expression | 逐像素在一个材质里混用多种着色模型 | — |
在延迟渲染下,着色模型 ID 写入 G-Buffer 供光照 pass 分支使用(通识,见 UE5 渲染架构)。
混合模式 (Blend Modes)
混合模式控制本材质(源色)如何与帧缓冲中已有颜色(目标色)合成。官方公式(Material Blend Modes):
| 模式 | 公式 | 动态光照 |
|---|---|---|
| Opaque | 兼容 | |
| Masked | 若 OpacityMask > Clip 值,否则丢弃像素 | 兼容 |
| Translucent | 表中标注不兼容 | |
| Additive | 不兼容 | |
| Modulate | 不兼容(贴花除外) | |
| AlphaComposite | (预乘 Alpha) | — |
| AlphaHoldout | 不兼容 |
要点:Masked 被裁掉的像素完全不绘制(因此也没有反射),但省 GPU;Clip 值不是为运行时修改设计的。Translucent 官方说明当前不支持高光反射,可用 Cubemap 叠加伪造。Additive 在亮背景上难以看清,可改用 AlphaComposite。AlphaHoldout 只能作用于其后的半透明类材质,不能打穿 Opaque。(Material Blend Modes)排序与 OIT 等通用问题见 透明渲染与 Alpha 混合。
材质实例 (Material Instances)
普通材质改图要重编译(复杂材质可能要近一分钟),而参数化材质可在材质实例里改值而不重编译。实例继承父材质全部属性,但只有在父材质中声明为参数的值可改:Scalar(单浮点)、Vector(4 通道)、Texture(如 TextureSampleParameter2D、Cube)等;常量不暴露。命名惯例 M_(父)/MI_(实例)。(Material Instances)
| 类型 | 何时计算 | 用法 |
|---|---|---|
| Material Instance Constant (MIC) | 运行前计算一次 | 内容浏览器创建;车漆颜色变体等 |
| Material Instance Dynamic (MID) | 运行时可改 | C++/蓝图 Create Dynamic Material Instance → Set Material;受损程度、实时换色 |
静态参数 (Static Parameters)(StaticSwitch、Static Component Mask)在编译期生效,被关掉的分支运行时不执行,但父材质中被实例使用到的每种静态参数组合都会编译一个新材质——这是着色器排列爆炸的主要来源,应尽量少用静态参数并控制实际使用的组合数。(Material Instances)
数据类型与 Custom / 翻译管线
材质图里流动的都是浮点:float / float2 / float3 / float4(Constant、Constant2/3/4Vector、Scalar/Vector Parameter、纹理)。Details 或节点内联写的值,一旦接到对应输入针脚就会被覆盖;Constant3Vector 可转成 Vector Parameter(实为 float4,float3 输入只用 RGB)。(Material Data Types、Essential Material Concepts)
创建材质后官方建议先设好 Material Domain / Blend Mode / Shading Model 三件套,它们决定主材质节点哪些输入可用(例如 Opaque 下 Opacity 灰掉)。(Essential Material Concepts)
手写 HLSL 与「图如何变成 CalcPixelMaterialInputs」不在本页展开:
| 需求 | 去向 |
|---|---|
查看/理解生成的 HLSL、常量折叠、FHLSLMaterialTranslator | 材质图到 HLSL 的翻译 |
| Custom 节点属性、函数局部输入、禁止折叠、HLSLcc 类型坑 | Custom 材质表达式 |
| 跨引擎 GLSL 片元练习(BoS / LearnOpenGL) | 片元着色器与 GLSL 基础 |
| 指令热度可视化 | UE5 性能分析 中的 Shader Complexity |
实践与坑
- 项目中常做少量「主材质 (Master Material)」+ 大量 MIC,运行时需要改的才建 MID(每个 MID 是独立对象,注意数量;此条为通识经验)。
- Metallic 用灰度过渡、Specular 当高光贴图用,都是旧工作流的常见错误。(Physically Based Materials)
- 材质域 (Material Domain) 决定材质的用途,有些用途(如贴花)需要渲染器做额外处理,所以非表面材质一定要设对(以下据 UE 5.7 Material Properties 页,5.8 页重定向未能抓取,Material Properties):
| 材质域 | 用途 |
|---|---|
| Surface | 默认值,物体表面(金属、塑料、皮肤等) |
| Deferred Decal | 贴花材质 |
| Light Function | 灯光函数 |
| Volume | 描述 3D 体积属性 |
| Post Process | 后处理材质(另有 Blendable Location 色调映射前/后、Blendable Priority、基于自定义深度/模板的 Stencil Test) |
| User Interface | UMG / Slate 界面 |
| Virtual Texture | 运行时虚拟纹理 (Runtime Virtual Texture) |
- 使用标记 (Usage Flags):只对 Surface 域有效,例如 Used with Skeletal Mesh / Niagara Sprites / Instanced Static Meshes / Geometry Collections。引擎为每种用途单独编译着色器版本;编辑器会自动勾选,但必须保存材质。游戏中缺少对应标记时会改用默认世界网格材质并在日志中提示。多勾标记会增加着色器编译时间和内存(如 Mesh Particles)。(Material Properties)
- 半透明光照模式:从最便宜的 Volumetric NonDirectional(不考虑法线,适合烟尘),到 Surface Translucency Volume(模糊但便宜,玻璃/水,只有漫反射),再到最贵的 Surface Forward Shading(逐像素计算每盏灯,支持局部光高光)。关闭深度测试会显著变慢。(Material Properties)
- Max World Position Offset Displacement:限制 WPO 的最大位移,并把包围盒外扩相同距离,防止裁剪和跳变;对按簇在 GPU 上剔除的 Nanite 尤其重要。代价是位移被夹住的地方会显得压扁,动画可能卡顿;可用 Out of Bounds Pixels 显示标记检查。(Material Properties)
- 粒子材质见 Niagara 粒子系统;PCG 的图实例机制与材质实例类似,见 PCG 程序化内容生成框架。
出处
- Materials (landing) UE 5.8 文档
- Material Instances UE 5.8 文档
- Shading Models UE 5.8 文档
- Physically Based Materials UE 5.8 文档
- Material Blend Modes UE 5.8 文档
- Material Properties UE 5.7 文档(5.8 页重定向)
- Essential Material Concepts UE 5.8 文档
- Material Data Types UE 5.8 文档
- Custom Material Expressions UE 5.8 文档
- How the Unreal Engine Translates a Material Graph to HLSL Epic KB