很多刚接触 UE5 的朋友学材质,第一反应是打开材质编辑器,照着教程拖几个节点,接上贴图,然后点击 Apply,看一眼效果。能跑通,但换一个模型、换一套灯光,效果就完全不对了。最典型的问题是:材质发黑、反光像塑料、贴图模糊、模型近看正常远看发灰。这时候绝大多数人会觉得是贴图问题,或者干脆重做一遍,但真正的原因往往出在没理解 PBR 的工作方式。
这一篇是 UE5 材质大师班的上篇,重点解决两件事:第一,真正理解 UE5 默认的 Metallic/Roughness PBR 工作流到底在做什么;第二,把从贴图准备、材质创建、材质实例到动态控制的一整条工作流跑通。文章不会只教你拖节点,而是告诉你每一步为什么这么做,遇到问题该看哪个环节。读完你可以自己创建一套带基础贴图、参数可调、可复用的材质工作流,也能自己排查材质变黑、法线错向、粗糙度失真等常见问题。
为什么“材质工作流”这个词值得重视?因为它不是一个炫技概念,而是决定你项目里所有物体“看起来对不对”“改起来快不快”“跑起来稳不稳”的核心框架。你可以花一下午拖出一堆漂亮节点,但如果没有工作流,项目一进入迭代阶段,调整一个全局粗糙度可能要改几十个材质;而工作流清晰的人,可能只需要改一个材质实例的参数。这就是这篇文章要帮你建立的能力。
1. 为什么说材质工作流决定你的作品上限
材质编辑器是 UE5 里自由度极高的一个模块,节点多、参数多、混合模式多,新手很容易陷入“记住节点”的误区。但如果你去问一个做了三五年场景或角色的 TA(Technical Artist),他会告诉你:材质本身不是难点,难的是怎么在正确的工作流里把材质组织起来。
所谓“材质工作流”,不是指某一个节点怎么用,而是从资产制作、贴图导出、材质创建、材质实例、运行时控制、性能优化,到最终在场景里验证的完整链路。它包含三层:
第一层是资源层。你手里有一套什么贴图,贴图的颜色空间是否正确,Normal 贴图的方向是否统一,Roughness 贴图是不是被压缩变形了,这些决定材质的底层质量。第二层是材质层。你把贴图接进哪些引脚,是否参数化,有没有做可复用的材质函数,这决定材质本身是否好用。第三层是控制层。你是直接改材质,还是通过材质实例调参,是否允许蓝图或 C++ 在运行时动态改变材质参数,这决定项目迭代效率。
很多项目做到后期,美术反馈“这个材质不好调”,其实问题不在材质本身,而在于没有把参数暴露出来,或者没有把功能拆成材质函数。相反,只要工作流设计得合理,一个基础材质加几个材质实例,就能覆盖场景里几十种不同表现,改起来还特别快。
所以,这篇文章不是在教你记节点,而是在帮你建立一套可持续迭代的材质工作流认知。先理解 PBR 光照模型,再掌握 UE5 材质系统的核心概念,最后落到一个完整示例。
2. PBR 基础:先搞懂 UE5 的光照模型
2.1 什么是 PBR
PBR 全称是 Physically Based Rendering,基于物理的渲染。它的核心思想是:用一套统一的参数来描述物体表面如何与光线交互,并且在不同光照环境下都能保持一致的视觉效果,而不是像传统渲染那样用一堆美术参数去“凑”一个效果。
UE5 默认使用 PBR,而且采用的是业界最流行的 Metallic/Roughness 工作流。这套工作流用四个核心贴图描述表面属性:Base Color(基础颜色)、Metallic(金属度)、Roughness(粗糙度)、Normal(法线)。理解这四张贴图,基本就理解了 PBR 材质的 80%。
2.2 四张核心贴图各自的职责
| 贴图 | 作用 | 典型颜色 | 常见误区 |
|---|---|---|---|
| Base Color | 描述表面漫反射颜色,金属表面则描述反射颜色 | 非金属黑白灰偏多,金属有明确颜色 | 金属贴了高光颜色导致过曝 |
| Metallic | 该区域是不是金属。0 为非金属,1 为金属 | 黑色非金属,白色金属 | 用灰度图当金属度,没有完全黑或白 |
| Roughness | 表面微观粗糙程度。0 光滑,1 完全粗糙 | 光滑偏黑,粗糙偏白 | 粗糙度贴图被 sRGB 处理导致颜色失真 |
| Normal | 用 RGB 编码的表面法线扰动,制造凹凸细节 | 偏蓝紫色 | 法线方向不对,或者贴图没有设置为 Normal |
这里有一个非常重要的认知:在 Metallic/Roughness 工作流里,Metallic 和 Roughness 是高度物理化的参数,它们不应该是随意调的数值,而应该来自真实材质扫描或者 PBR 贴图生成工具。很多新手为了“好看”把 Metallic 拉到 0.8,结果金属表面看起来像脏了的塑料,这是因为能量守恒被打乱了。
2.3 能量守恒与 UE5 的默认处理
PBR 渲染有一个核心原则叫能量守恒:光线打到表面上,要么被反射,要么被折射进内部,要么被吸收,总能量必须守恒。换句话说,高光反射越强,漫反射就应该越弱;金属表面几乎没有漫反射,因为所有光线都参与镜面反射,所以金属的 Base Color 实际上存的是反射颜色,而不是漫反射颜色。
UE5 的默认光照模型已经帮你把能量守恒做了大部分处理,你不需要理解复杂的反射方程。但你得明白:如果你粗暴地把一个非金属材质的 Metallic 改成 1,它依然不会变成正确的金属,因为它的 Base Color 还是漫反射颜色,反射出来就怪怪的。更合理的做法是同时调整 Base Color 和 Metallic,确保两者来自同一个材质语义。
2.4 为什么 UE5 默认选 Metallic/Roughness 而不是 Specular/Glossiness
市面上还有另一套工作流叫 Specular/Glossiness,它用 Specular 贴图代替 Metallic,用 Glossiness 代替 Roughness。那为什么 UE5 默认用 Metallic/Roughness?原因很实际:
Metallic/Roughness 更直观。Metallic 只有 0 和 1 两个极端有意义,中间值在物理上很少出现。美术只要判断“这东西是不是金属”就能填对。Roughness 也是从光滑到粗糙的直观线性变化。而 Specular 贴图需要美术同时理解漫反射、高光和镜面反射的区别,心智负担更大。
从工具链角度看,Substance Painter、Quixel Bridge、Mixer 等主流 PBR 工具导出的默认贴图组合就是 Base Color、Metallic、Roughness、Normal。UE5 选择这套工作流,接模型的时候几乎是零成本。所以,绝大多数情况下,你没有理由更改默认的色彩模型和着色模型,直接用就好。
2.5 一个最小案例:为什么同样的材质换光照就变差
假设你做一个红色塑料材质:Base Color 是深红,Metallic 是 0,Roughness 是 0.4。在暖光下看起来不错,换到冷光下就发灰发闷。这不是材质错了,而是 PBR 材质本身不“自发光”,它只正确响应光照。很多新手把“材质效果”和“光照效果”混在一起,结果在写实项目里拼命调材质,却忘了检查场景里的光照强度和色温。
这也是为什么我会反复强调:判断材质是否正确,请先保证场景里有一个合适的光照环境,比如用 UE5 自带的 BaseLighting 模板,或者放置一个 Directional Light 加 SkyLight。材质没问题的情况下,光照环境不对,效果依然会翻车。
3. UE5 材质系统核心概念与节点编辑器布局
3.1 材质、材质实例、材质函数
UE5 材质系统三个最基础的单位是 Material(材质)、Material Instance(材质实例)和 Material Function(材质函数)。你可以把材质理解成一个“原始作者”资产,它在材质编辑器里定义了完整的颜色、贴图、混合逻辑;材质实例是这张材质的“派生副本”,它不能改节点的连接结构,但可以调整在母材质里暴露出来的参数;材质函数则是一段可复用的节点逻辑,像函数一样被其他材质调用。
三者的关系和 C++ 的类、实例、函数非常像:动态材质实例就相当于一个实现了多态的对象,运行时可以安全地改参数,而不会污染母材质。
3.2 材质域、混合模式与着色模型
新建材质时,最上层有一排关键下拉选项,新手经常忽视,但它们决定了材质在所有情况下的行为:
材质域(Material Domain)控制这张材质用在什么地方。常见的有 Surface(常规表面)、Deferred Decal(延迟贴花)、Volume(体积)、Light Function(灯光函数)、User Interface(UI)等。选错材质域,材质就完全不可用。比如你把一个普通表面材质拖到 UI 上,它会直接报错。
混合模式(Blend Mode)决定表面如何与背景混合。Opaque 是不透明;Masked 是带硬边缘裁剪,通常用来做树叶、铁栏;Translucent 是真正的半透明,用来做玻璃、水、特效。注意 Translucent 是排序敏感的,两个半透明物体互相遮挡时,会有穿帮,这是引擎限制,不是你的错。
着色模型(Shading Model)决定如何使用光照。默认的 Default Lit 管绝大多数表面;Subsurface 用于皮肤、蜡烛、树叶的次表面散射;Clear Coat 用于车漆、涂层;Cloth 用于布料;Eye 用于眼球。合理选择着色模型,比堆节点更重要。
3.3 节点编辑器布局
材质编辑器左侧是 Palette(节点面板),中间是画布,右侧是 Details(详情面板),左上角还有一个“预览视口”,提供球体、平面、圆柱等预览网格体。建议你把节点分组框(Comment Box)用起来:把贴图采样、数学计算、最终输出分别放三个框,并写成英文或中文注释。项目一大,这能省很多时间。
预览视口很关键,但有个坑:预览网格体和你的实际模型不同,灯光环境也和场景不同,所以预览好看不代表放到场景里也好看。建议在场景里放一个测试用平面或立方体,直接把材质拖上去看实际效果,这比盯着预览视口更准确。
4. 环境准备与贴图资源规范
4.1 软件与版本
本文以 UE5 系列版本为基准,版本差异不影响核心原理,但建议使用 5.1 及以上版本,界面和节点稳定性更好。创建项目时选择 Blank 模板或 Third Person 模板都可以,材质功能差异不大。
这里不展开具体操作,但有一个值得养成的习惯:项目命名用英文小写加下划线,素材目录清晰分层。比如Content/Materials/Props、Content/Textures/Props/Desk。UE5 对中文路径和虚拟路径支持不太好,团队协作时更容易出问题。
4.2 贴图资源规范
做 PBR 材质前,你要先检查手上的贴图是否达标。常用规范如下:
Base Color 贴图使用 sRGB 颜色空间,这是唯一一张应该用 sRGB 的贴图。Metallic、Roughness、Normal、AO 都是非颜色数据,导入 UE5 时应该把 sRGB 关闭,否则这些数据会被加一个 Gamma 校正,导致粗糙度偏灰、法线凹凸变弱。这一点是新手最容易忽略的,也是“材质看起来脏”的常见原因。
贴图尺寸建议根据项目类型决定。写实次世代项目常用 2K,大场景远景纹理可以用 1K,角色特写或高精度道具可能用到 4K。移动端项目要谨慎,建议 512 或 1K。纹理尺寸不是越大越好,内存和加载时间是硬成本。
Normal 贴图要注意坐标方向。UE5 和 Maya、Substance 都使用右手坐标系的 DirectX 风格法线,但某些建模软件导出的是 OpenGL 风格,需要做绿通道翻转。在 UE5 的贴图导入设置里,找到 Texture 的 Flip Green Channel 选项,勾选后就能转换。
4.3 创建一个材质文件夹
在 Content Browser 里新建文件夹Materials,里面再按资产类型建子文件夹。新建一个测试用材质,命名为M_Test_Desk,命名前缀 M_ 表示 Material,这是业界通用约定。别小看命名规范,项目大了之后,一个叫NewMaterial_3的材质会让所有人都崩溃。
5. 从零创建第一个 PBR 材质(上篇核心实操)
5.1 新建材质并设置基础属性
在Materials文件夹右键,选择“材质”,命名为M_PBR_Prop。双击打开材质编辑器。什么都不用改,先用默认设置跑通一个最简单的 Base Color 颜色材质:从 Palette 搜索Constant3Vector,放到画布,连接到底板上的 Base Color 引脚,点击 Apply,再回到场景里把它拖到一个模型上,模型就会变成这个颜色。
这一步虽然简单,但很重要,它验证了材质链路是通的,后面再怎么加贴图,链路逻辑都一样。
5.2 接入第一张贴图:Base Color
在画布右键搜索TextureSample(也可以直接叫 Texture Sample 节点),选中后把它的输出连接到 Base Color。这个节点需要一个贴图输入,在 Details 面板里把导入好的 Base Color 贴图赋给它。点击 Apply,模型上就能看到颜色纹理。
这里有一个文本思路的节点连接图,方便你快速复刻,我用缩进表示节点连接关系:
M_PBR_Prop 材质主节点 |-- Base Color 引脚 <-- TextureSample (BaseColorTexture) 节点的 RGB 输出 |-- Metallic 引脚 <-- TextureSample (MetallicTexture) 节点的 R 输出 |-- Roughness 引脚 <-- TextureSample (RoughnessTexture) 节点的 R 输出 |-- Normal 引脚 <-- TextureSample (NormalTexture) 节点的 RGB 输出为什么 Metallic 和 Roughness 只取 R 通道?因为这类灰度贴图的信息在 R 通道就够用了。有些压缩格式会用 BC5 保存灰度数据,R 通道就是有效数据。当然你也可以把整张灰度图直接接到 Metallic 引脚,UE5 会自动取亮度,但显式取 R 通道语义更清楚,性能也更稳定。
5.3 接入法线贴图
在画布搜索TextureSample,创建一个新的,导入 Normal 贴图,把 RGB 输出连接到主节点的 Normal 引脚。法线贴图不需要勾选 sRGB,这一点在上一章提过,导入贴图时要注意勾掉。
在 UE5 里还有一个比普通 TextureSample 更推荐的法线接入方式:TextureSampleNormal节点,它把贴图作为法线采样,并且自动处理法线压缩,更适合直接用在 Normal 引脚上。这个节点在细节面板里同样可以指定法线贴图。
5.4 参数化:把颜色和数值变成可调参数
现在材质是写死的,不便于复用。我们把 Base Color 贴图和 Roughness 数值参数化:选中连接在 Base Color 上的 TextureSample 节点,右键,选择“转换为参数”,它会生成一个TextureSampleParameter2D节点,参数名默认为 BaseColorTexture;同样的方法把 Metallic 和 Roughness 贴图也转成参数。
对 Roughness 这一步,更常见做法是加一个ScalarParameter(标量参数),命名为 RoughnessValue,设置默认值 0.5,连接一个Multiply节点,把贴图的 R 输出和 RoughnessValue 相乘,再连到主节点的 Roughness 引脚。这样你就多了一个“粗糙度缩放”控制,在材质实例里就能整体调整粗糙度,非常实用。Mul 节点在材质里是最常用的数学节点之一,连接关系如下:
TextureSample (RoughnessTexture) R 输出 |--> Multiply (b) ScalarParameter (RoughnessValue, 默认 0.5) |--> Multiply (a) Multiply 结果 --> 主节点 Roughness 引脚同样方式,你可以对 Metallic 也做一个 MetallicValue 标量参数,默认值 0,方便在不改贴图的情况下微调整体金属度。Base Color 的 RGB 输出也可以再接一个 Color 参数做整体颜色倍乘,这样美术可以直接在材质实例里调整“偏冷”“偏暖”“变暗”等效果,而不必回到贴图里去改。
5.5 创建材质实例
创建好母材质后,在 Content Browser 里右键材质,选择“创建材质实例”,命名为MI_PBR_Prop。双击打开材质实例编辑器,你会发现右侧一堆参数,包括刚才创建的 TextureSampleParameter2D 和 ScalarParameter。这里可以独立修改参数而不用碰母材质。
材质实例编辑器的使用逻辑是:先勾选参数前面的复选框,参数才可编辑;否则材质实例会沿用母材质的默认值。RoughnessValue 勾选后可以从 0 表光滑、1 表粗糙调整。这一步就是工作流的核心价值:场景里不同的物体,可以通过同一个 MI 快速调整粗糙度、金属度、颜色,完全不需要重新编译材质。
在材质实例编辑器里,顶部有一个“资产”选项卡,可以直接刷新材质、查看父级材质。把 MI_PBR_Prop 拖到场景里的多个模型上,再修改 RoughnessValue,你会发现所有模型同步变化。这就是工作流效率的直观感受。
5.6 如何验证材质是否正确
验证 PBR 材质是否正确,不需要多复杂的工具。准备两个测试物:一个球体、一个平面;放一盏足够亮且方向明确的 Directional Light,再放一个 SkyLight。把材质拖到球体上,重点看几个表现:
高光是否清晰且大小合理;非金属区域的高光颜色是否接近灯光颜色而不是变黄;金属区域是否反射出明显的高光形状;暗部是否没有死黑或过曝。如果材质看起来“塑料感”过强,通常不是材质问题,而是场景里缺少环境反射,建议在场景里放一个 SkyLight 或 SkyAtmosphere,甚至可以临时放几个大体积反射球,增加反射信息。
6. 常用材质节点的工作流意义
连接完基础 PBR 贴图之后,你肯定会在更多材质里遇到一堆高频节点。这里挑几个最常见的讲,它们背后都有明确的工作流意义。
6.1 Constant3Vector 与 Color 参数控制的差异
Constant3Vector 是常量颜色,写死不可调;VectorParameter 是颜色参数,可以在材质实例里调整。开发时尽量用 VectorParameter,哪怕暂时不需要改。因为交给美术后,他们大概率会想调整颜色,而你预留一个参数只需要几秒钟,但后面重新链接节点重新编辑材质浪费时间。
类似的经验是:所有可能变化的数值,都优先用 ScalarParameter。比如自发光强度、贴花淡入淡出、细节法线强度、视差偏移量等,全部参数化。这是“材质可迭代”的关键一步。
6.2 Lerp:万能混合节点
Lerp(线性插值)是材质里最关键的数学节点之一,它接收两个输入 A、B 和一个 Alpha 值,输出 A*(1-Alpha)+B*Alpha。换句话说,Alpha 为 0 输出 A,为 1 输出 B。
工作流里最常见的用法是做“粗糙度渐变混合”。比如地板上的湿润区域,你可以用一张 Mask 贴图或顶点色作为 Alpha,把干燥粗糙度和湿润粗糙度混在一起。连接关系如下:
VectorParameter (DryColor) --> Lerp A VectorParameter (WetColor) --> Lerp B TextureSample (MaskTexture) --> Lerp Alpha Lerp Result --> Base Color 引脚这个模式可以扩展到 Metallic、Roughness、Emissive,只需要把输入换成对应的参数。做多层材质叠加时,Lerp 就是工作流的粘合剂。
6.3 Multiply、Clamp 与 Power 的数值修正
Multiply 是最常见的数学运算。对 PBR 材质来说,贴图输出 × 标量参数是一个基础模式。但要小心相乘后数值超过 1,尤其是你把 Base Color 和颜色参数相乘时,可能让亮度溢出,导致高光过曝。这时需要加一个 Clamp,限制数值在 0 到 1 之间。
Power 通常用来增强对比度或调整高光的衰减。比如你有一个 Mask 贴图,希望边缘更锐利,就可以用 Power 提升中间调对比度。
6.4 Fresnel:边缘与视角的关系
Fresnel 节点基于视角计算边缘光,常用于给金属、玻璃、显示器屏幕增加边缘反射。它的核心原理是:视角越倾斜,反射越强。UE5 的 Fresnel 输出一个 0 到 1 的数值,配合 Power 调整边缘宽度。可以用于表面边缘高光、非地面层的遮挡效果等。
连接关系如下:
Fresnel 输出 --> Power (Exponent = 5) Power 结果 --> Multiply (强度参数) Multiply 结果 --> Emissive Color 引脚这样物体会在边缘产生微弱的辉光。但注意 Emissive 是自发光,会破坏 PBR 的物理正确性,只适合在需要视觉引导时用,不要把它当成常规加光方式。
6.5 顶点色混合工作流
顶点色(Vertex Color)是另一个非常实用的工作流工具。美术在建模软件里给模型顶点刷上颜色,UE5 材质里用VertexColor节点读取红、绿、蓝、Alpha 通道,作为 Lerp 的 Alpha 实现贴图混合。这样只需要一张材质、一套贴图,就可以在同一个模型上混合出草、泥土、岩石三种地表效果,比拆多个材质再用 Material Layer Blend 简单得多。
具体思路:用 VertexColor.R 作为 Lerp 的 Alpha,把草地贴图和泥土贴图混合;再用 VertexColor.G 作为另一个 Lerp 的 Alpha,把上一轮混合结果和岩石贴图混合。这样地表材质就有三种贴图自由混合,而且不同区域的过渡由顶点色控制。这种工作流在地形和废墟类场景里非常高效。
7. 从零散节点到可复用工作流:材质实例与材质函数
7.1 先整理节点,再谈效率
新手拖节点时的常见问题,是画布上一团乱麻。相信我,有经验的材质师也会觉得自己的节点很乱,但他们会在交付前做一次整理:把相关节点用 Comment Box 框起来,快捷键 Ctrl+W 可以缩放框选范围,给每个框写中文注释。这样做不仅方便自己复盘,也方便团队其他人接手。
建议每个材质至少分三个框:InputTextures(输入贴图)、MathAdjust(数学调整)、Output(输出)。Output 框里只放最终连接到主节点的那几个引脚。
7.2 封装一个“PBR 贴图连接”材质函数
当你接了好几套不同贴图的材质后,会发现重复劳动太多:每个材质都要加 Base Color 贴图节点、法线贴图节点、粗糙度贴图节点,再各自接引脚。一个项目有几十个材质,就要重复几十次。解决办法是封装一个材质函数。
在 Content Browser 中创建“材质函数”,命名为MF_StandardPBR,双击打开材质函数编辑器。放入四个 TextureSampleParameter2D 节点,分别命名为BaseColor、Metallic、Roughness、Normal,再把它们的输出分别连到四个 Output 节点上,也将这四组参数暴露为函数输入。函数节点文本示意:
MF_StandardPBR 输入输出定义 |-- Input: BaseColorTexture (TextureSampleParameter2D) |-- Input: MetallicTexture (TextureSampleParameter2D) |-- Input: RoughnessTexture (TextureSampleParameter2D) |-- Input: NormalTexture (TextureSampleParameter2D) |-- Input: RoughnessScale (ScalarParameter, 默认 0.5) |-- Output: BaseColor |-- Output: Metallic |-- Output: Roughness |-- Output: Normal保存后,在任何材质里搜索MF_StandardPBR,拖进来,就会看到四个输入引脚和四个输出引脚。你只需要把贴图参数赋给材质函数的输入,再把输出接到主节点,一个完整 PBR 材质的骨架就搭好了。这样后续维护只需要改这一个函数,接入了该函数的所有材质都会同步更新,这是工作流的典型好处。
7.3 用蓝图在运行时控制材质参数
静态的工作流靠材质实例,动态的工作流则需要蓝图或 C++ 在运行时修改材质参数。最常见的需求是:玩家靠近时物体发光变暗、踩踏时地面粗糙度变化、武器充能时 Emissive 强度上升。
做法是给模型创建动态材质实例。最稳的方式是在蓝图里提前创建并缓存,而不是每帧调用CreateDynamicMaterialInstance。下面的 C++ 示例展示了一个 Actor 在BeginPlay时获取动态材质实例,并在 Log 中打印参数值,方便验证。注意它只是演示接口,游戏逻辑通常会在具体事件里调用。
// 文件路径:Source/YourProject/Public/YourActor.h #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "YourActor.generated.h" UCLASS() class YOURPROJECT_API AYourActor : public AActor { GENERATED_BODY() public: AYourActor(); protected: virtual void BeginPlay() override; UPROPERTY(VisibleAnywhere, BlueprintReadOnly) class UStaticMeshComponent* MeshComp; // 缓存的动态材质实例,避免每帧创建 class UMaterialInstanceDynamic* DynamicMat; UFUNCTION(BlueprintCallable, Category = "Material") void SetRoughness(float NewRoughness); };// 文件路径:Source/YourProject/Private/YourActor.cpp #include "YourActor.h" #include "Materials/MaterialInstanceDynamic.h" #include "Components/StaticMeshComponent.h" AYourActor::AYourActor() { PrimaryActorTick.bCanEverTick = false; MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComp")); RootComponent = MeshComp; } void AYourActor::BeginPlay() { Super::BeginPlay(); if (MeshComp && MeshComp->GetMaterial(0)) { DynamicMat = MeshComp->CreateAndSetMaterialInstanceDynamic(0); if (DynamicMat) { // 创建一个用于演示的参数,材质中请先建立同名标量参数 DynamicMat->SetScalarParameterValue(FName("RoughnessValue"), 0.3f); UE_LOG(LogTemp, Warning, TEXT("Dynamic material created and roughness set.")); } } } void AYourActor::SetRoughness(float NewRoughness) { if (DynamicMat) { DynamicMat->SetScalarParameterValue(FName("RoughnessValue"), NewRoughness); } }这段代码的核心是CreateAndSetMaterialInstanceDynamic(0),它从模型第 0 号材质创建动态实例,且会直接替换模型当前使用的材质。之后所有SetScalarParameterValue/SetVectorParameterValue都作用于这个实例,不会影响磁盘上的原始材质资产。
在纯蓝图项目里,节点序列相对应的是:在事件图表中调用创建动态材质实例节点,把返回的动态材质实例存入变量,再用设置标量参数值/设置矢量参数值节点改参数。注意参数名必须和母材质里创建的参数名完全一致,大小写也要一致,否则运行时设置无效。你可以这样组织蓝图节点序列,便于对照实现:
Event BeginPlay |--> Create Dynamic Material Instance (MeshComp, 材质索引 0) |--> 存入 DynamicMat 变量 |--> Set Scalar Parameter Value (DynamicMat, "RoughnessValue", 0.3) |--> Print String ("Dynamic material created")另一种可复用的做法是:把材质实例做成资产,在蓝图里用SetStaticMesh后调用SetMaterial用实例资产覆盖,这样美术在编辑器里调好的参数也能保留,但复杂度会高一些。常规游戏逻辑优先用动态材质实例方案。
7.4 何时选母材质、材质实例、动态材质实例
| 层级 | 使用场景 | 优缺点 |
|---|---|---|
| 母材质 | 定义材质核心逻辑 | 灵活但修改成本高,不易被美术直接使用 |
| 材质实例 | 场景里静态物体的常用方式 | 直观、可调、可继承,适合大多数静态资产 |
| 动态材质实例 | 运行时需要改变参数 | 不污染资产,但要在代码或蓝图里管理生命周期 |
一个关键实践是:凡是美术会反复调的东西,优先做母材质参数并创建材质实例。凡是逻辑控制会改的东西,运行时用动态实例。不要直接在母材质里改参数跑预览,一定要养成“创建材质实例再调参”的习惯。
8. 常见问题与排查思路
材质问题排查有个基本思路:自上而下,先看贴图导入,再看节点连接,再看场景光照。下面整理几个高频问题。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 材质整体变黑 | 法线贴图方向错误,或贴图压缩导致颜色不对,或场景无反射 | 检查 Normal 贴图 Flip Green Channel 是否该勾选;在场景加 SkyLight | 修正法线方向,把贴图压缩设置为 TC Normalmap;给场景补环境光 |
| 金属表面看起来像塑料 | Metallic 不是 0 就是 1,没有使用金属颜色 | 预览金属度数值,检查 Base Color 是否为金属反射颜色 | 正确设置 Metallic 和 Base Color,不要用中间值 |
| 粗糙度变化不明显 | Roughness 贴图 sRGB 未关闭,数值被 Gamma 校正 | 打开贴图资源,检查 sRGB 是否勾选 | 关闭 sRGB,重新导入或修改压缩设置 |
| 半透明排序错误 | Translucent 材质互相遮挡顺序不对 | 查看物体渲染顺序 | 手动调整 Sort Priority,或拆分物体避免半透明交叉 |
| 贴图模糊 | 纹理尺寸过小或压缩格式不合适 | 查看贴图导入尺寸和压缩设置 | 调整纹理大小,使用合适的压缩格式 |
| 高光过曝或发灰 | PBR 参数 与 灯光强度不匹配,或没有使用 sRGB 颜色空间 | 检查材质参数和灯光强度 | 将 Base Color 设置在合理范围,调整灯光强度和色温 |
| 动态参数设置无效 | 参数名大小写不一致,或参数没有在母材质里创建 | 打印参数名并检查宏定义 | 统一参数命名,确认母材质中存在同名标量/向量参数 |
另一个容易被忽略的问题是 Compile 错误。节点是红色或断开时,鼠标悬停上去会有警告信息,大部分可归为引脚类型不匹配或连接数量不对。第一步先看输出日志,第二步把错误涉及的节点拖到一侧排查,不匹配的引脚类型通常是float和vector接错,用ComponentMask或Break拆开处理即可。
材质预览效果和场景效果不一致也是常见问题,原因通常是预览球受固定灯光影响,而场景里有实时反射、体积光或后处理。遇到这种情况,直接在场景放置一个测试用模型,把材质拖上去,用游戏视角观察。不要执着于预览视口里的球体。
9. 上篇总结与下篇预告
这一篇,我们从 PBR 光照模型的底层逻辑讲起,理清了 Metallic/Roughness 工作流中四张贴图各自的作用,也讲了 UE5 材质系统的三个核心资产:材质、材质实例、材质函数。然后通过一个完整的 PBR 材质创建示例,把从贴图导入、节点连接、参数化到材质实例调参的路径完整走了一遍。最后,我们用材质函数和动态材质实例,把“会做材质”提升到“有材质工作流”的层面。
你应该已经掌握的是:在 UE5 里创建一个基础 PBR 材质不再只是“拖节点接贴图”,而是有意识地把贴图导入、参数命名、材质实例、动态控制作为一个整体考虑。你也应该能看懂自己项目中现有材质为什么效果不对,并且知道从贴图导入还是节点连接开始排查。
下一篇,也就是下篇,我们会深入更高级的材质制作工作流:程序化纹理与噪声算法、Material Layer 的图层化混合、视差遮蔽映射(POM)、Detail 法线与三平面映射、水体材质、地形材质自动混合,以及在移动端和 VR 场景下的性能优化技巧。到那时,你会发现,上篇打好的是地基,下篇才是在地基上盖楼。
先别急着继续学新节点,建议你现在就打开 UE5,用本文的方法把一个普通道具的材质重建一遍:检查导入贴图是否关掉了 sRGB,把 Base Color、Roughness、Metallic、Normal 正确接入,参数化后用材质实例调一遍。这个过程如果能顺利走通,说明你已经掌握了 UE5 材质制作的基础工作流,也就可以放心地进入下一阶段了。
如果这篇文章对你有帮助,建议收藏备用,下一篇大师班见。