ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

UE5材质工作流进阶:PBR原理、材质函数与阴影优化实战

UE5材质工作流进阶:PBR原理、材质函数与阴影优化实战 之前我们把 PBR 的基础理论、贴图通道的含义、材质编辑器的基础操作都过了一遍能明显感觉到材质系统并不难上手难的是从“会摆节点”升级到“能根据项目需求搭建一套稳定、高效、可复用的材质制作工作流”。尤其是真正进入 UE5 项目后会遇到大量与地表、植被、建筑、角色皮肤、特效材质相关的场景这时候单靠一个材质节点连 BaseColor 已经远远不够。这篇文章是材质大师班的下半部分重点解决三件事第一把 PBR 材质从“拼贴图”提升为“搭流程”第二用完整的实战案例演示地表混合材质、材质函数、材质层等高级组织方式第三拆解一个非常典型的项目问题——模型不透明遮罩做材质生长时阴影不实时变化。最后我会把材质性能优化和工程规范一起整理进来。如果你已经掌握了 UE5 材质编辑器的基础操作这篇可以直接照着做如果你还是新手建议先把材质编辑器常用节点过一遍再回来体验会顺畅很多。1. UE5 PBR 材质体系回顾与节点思维1.1 着色模型决定材质上限在 UE5 材质编辑器里新建材质后第一件事不是连节点而是确认两个属性材质域Material Domain和着色模型Shading Model。材质域决定了这个材质在渲染管线中扮演什么角色。项目里最常见的材质域是 Surface表面模型、地表、植被这类普通网格都走这个域。除此之外还有 Deferred Decal延迟贴花、Light Function灯光函数、Volume体积、Post Process后期处理和 User InterfaceUI这几个域。不同域的可用输出引脚完全不同例如 Post Process 材质没有 BaseColor取而代之的是 Emissive 用于驱动后期效果。着色模型则决定了材质输出引脚如何参与光照计算。UE5 默认的 Default Lit 是 PBR 项目的通用选择它能正确响应直接光、间接光、阴影、反射和 GI。除了 Default Lit还有 Subsurface次表面、Clear Coat清漆、Cloth布料、Eye眼睛、Hair毛发等专用模型。选择着色模型时有一个原则能用 Default Lit 就不要换专用模型因为专用模型通常有额外的性能开销和贴图需求。比如做皮肤时如果没有 SSS 需求用 Default Lit 加上合适的 Roughness 也能得到不错的效果。这一节要记住的结论是材质域和着色模型是整个材质的上层架构一旦选错后续所有节点逻辑都会在错误的渲染路径上运行项目越往后越难改。1.2 几个高频节点的底层行为在材质编辑器中节点是构建逻辑的最小单元。很多初级开发者能把节点连出效果但遇到报错或性能问题时无从下手本质原因是只记住了“怎么连”不知道节点在 GPU 上做了什么。下面几个节点是高级工作流里反复出现的先理清它们的底层行为。Texture Sample纹理采样它的核心动作是从显存中读取纹理并输出颜色值。读取纹理需要知道 UV 坐标默认使用 mesh 自带的 UV0。当同时采样多张纹理时需要注意 UV 通道分配。另外纹理采样最容易被忽略的是 Mip Level 和 Filter 设置。UE5 中可以让引擎自动计算 Mip 层级也可以手动指定在粒子材质或 UI 材质中手动控制 Mip 能避免闪烁问题。Lerp线性插值这是材质逻辑中最常用的混合节点公式是Lerp(A, B, Alpha) A (B - A) * Alpha。Alpha 为 0 时输出 A为 1 时输出 B中间值做平滑过渡。很多人把 Lerp 当作“条件切换”来用其实它的正确语义是“线性混合”。例如做地表混合时Alpha 通道来自权重贴图或顶点色不同位置有不同的权重值Lerp 产生的是渐变而不是生硬切换。VertexColor顶点颜色这个节点读取静态网格每个顶点的颜色值。顶点颜色最大的优势是零额外贴图美术可以直接在建模软件里刷权重也可以在 UE5 的 Mesh Paint 模式里刷。缺点也很明显——顶点分辨率有限离近看会出现权重过渡不细腻的情况。所以顶点颜色适合做大体块的材质混合不适合做大面积精细纹理切换。Constant / ScalarParameter / VectorParameter这三类节点代表不同的参数管理方式。Constant 是写死的常量适合不打算调整的内容ScalarParameter 和 VectorParameter 是材质参数可以在材质实例中覆盖适合需要频繁调节的内容。工程建议很明确只要是“可能会调”的值一律用 Parameter不要图省事用 Constant否则后期调参数时效率会非常低。理解了这些底层行为后再去看高级材质工作流就会发现很多“技巧”其实只是对这些基础节点更合理的组合。2. 面向项目落地的材质制作工作流2.1 从参考图到材质拆解很多人在拿到一张参考图后直接打开材质编辑器开始连节点这是效率最低的方式。正确的做法是先拆解参考图明确材质需要的贴图通道和混合逻辑。举个例子假设要做一面岩石墙面参考图里能看到岩石主体有颜色差异、表面有凹凸感、部分区域有青苔覆盖、整体有不同程度的粗糙度变化。拆解后就得到这样一张清单材质要素需要的贴图/参数对应材质输出引脚岩石颜色变化BaseColor 贴图 或颜色参数BaseColor表面凹凸感Normal 贴图Normal粗糙度差异Roughness 贴图Roughness金属元素Metallic 贴图Metallic青苔覆盖范围混合权重贴图 或顶点色用于 Lerp 的 Alpha环境光遮蔽AO 贴图Ambient Occlusion拆解完之后再进入材质编辑器你会很清楚每个节点输出的内容要接到哪里不会出现“连接头”满天飞却不知道在做什么的情况。这个拆解能力是高级材质工作流的核心它比多记几个节点技巧重要得多。2.2 贴图通道与命名规范贴图整理是材质工作流里最容易乱的一环。项目一旦超过十个材质如果贴图命名和目录不规范后期查找和排查会非常痛苦。推荐一套经过多个项目验证的命名规范T_材质名_通道 T_Grass_BaseColor T_Grass_Normal T_Grass_Roughness T_Grass_Metallic T_Grass_AO也可以采用带版本后缀的方式比如T_RockWall_BC_v01便于纹理迭代时保留历史版本。目录方面建议在 Content 下建立Materials、Textures、MaterialFunctions、MaterialLayers四个目录分别存放材质资产、贴图资产、材质函数和材质层。这样整个项目资产结构从根上就是清晰的。贴图导入 UE5 后还需要检查纹理压缩设置。不同通道的贴图应该使用不同的压缩格式BaseColor 通常使用 BC1RGB或 BC7高精度颜色Normal 贴图必须设置为“法线贴图”压缩格式否则法线方向会错误Roughness、Metallic、AO 这类单通道贴图建议放入一张纹理的 RGB 或 A 通道尽量共用一个贴图资源减少纹理采样次数。2.3 材质实例参数规划UE5 的材质实例Material Instance是材质工作流不可或缺的一环。母材质Master Material负责写逻辑子材质实例负责调参数。这样做有一个巨大的好处修改母材质的节点逻辑时所有实例会自动同步更新不需要逐个调整而且在实例中暴露的参数越多项目调整起来越灵活。但参数规划也有边界。如果母材质把几十个参数全部暴露出来实例面板会非常臃肿不利于规范和排查。推荐的做法是只暴露两类参数——一类是跨场景需要变化的颜色和数值比如植被颜色的季节变化、墙面脏污强度的调节另一类是切换贴图用的纹理参数。写死的逻辑常量继续用 Constant 保存在母材质内部。另外UE5 提供了 Material Parameter Collection材质参数集合可以在全局或关卡范围内共享参数适合做全局风场强度、全局湿度、全局雪花覆盖这类跨材质变量。熟练使用参数集合可以让多个材质在同一变量驱动下产生联动效果比如下雨时所有地表材质同步加湿。3. 实战案例一地表材质与顶点颜色混合前面把工作流的核心思路理清了接下来用一个完整的地表混合材质案例走一遍流程。这个案例是开放世界、室内地编、建筑外立面项目中很常见的地表混合需求。3.1 创建地表材质在 Content 下新建Materials目录右键选择Material命名为M_AdvancedGround。双击打开材质编辑器先把材质属性设置好Material Domain 保持 SurfaceShading Model 选择 Default Lit勾选 Used with Static Lighting如果项目使用烘焙光照Two Sided 视需求开启接着准备两组贴图资源草地贴图和岩石贴图每组包含 BaseColor、Normal、Roughness 三张贴图。在材质编辑器中创建两个 Texture Sample 节点分别采样草地的 BaseColor 和岩石的 BaseColor然后将两个输出接入同一个 Lerp 节点的 A 和 B 输入。到这里Lerp 的 Alpha 还没有来源先接一个 Constant默认值 0.5。此时预览窗口会看到草地和岩石各混合一半的效果。继续给 Lerp 的输出接入材质的 BaseColor 引脚。同样的方式处理 Normal 和 Roughness创建对应的 Texture Sample接入各自的 Lerp输出到 Normal 和 Roughness 引脚。需要说明的是两个材质域的 Normal 混合不能直接使用 Lerp 节点而是需要使用BlendAngleCorrectedNormals节点否则法线在交界处会出现明显的接缝光照错误。因此在法线通道的连接中结构应该是草地 Normal → BlendAngleCorrectedNormals 的 A岩石 Normal → B输出到 Normal 引脚。Roughness 通道仍可使用普通 Lerp因为粗糙度是标量直接线性混合物理上是合理的。这样一个基础的两层地表混合材质就完成了。3.2 使用顶点颜色做权重混合把刚才 Lerp 节点的 Alpha 从 Constant 换成 VertexColor 节点输出使用 VertexColor 的 R 通道。这样同一个材质在顶点颜色 R 为 1 的区域完全显示岩石R 为 0 的区域完全显示草地中间值形成平滑过渡。在 UE5 场景中选中目标地面模型在编辑模式中选择Mesh Paint模式选择 Paint Color用合适的颜色对地面刷顶点色。刷的时候注意只刷红色通道即把颜色设置为 (255, 0, 0) 到 (0, 0, 0) 之间的红色梯度这样权重逻辑才一致。顶点混合方式对比材质层混合它的优势是轻量、直观、不需要维护多层材质资产适合地形模型和小型建筑外立面。缺点是顶点权重精度有限超大面积地表如果只用顶点色会出现权重过渡粗糙的问题。这种场景更适合使用 Landscape 的地形材质体系或者在制作模型时烘焙高分辨率的 AO 权重贴图。3.3 运行验证完成节点连接后点击 Apply 和 Save将材质拖到场景中的地面模型上。切换到 Lit 模式观察应该能看到草地和岩石之间有平滑的过渡区域同时在过渡区域的法线接缝不会出现明显破绽。如果过渡区域出现硬边通常是顶点色刷得太突兀如果过渡区域出现闪烁或锯齿考虑增加模型顶点密度或者改用高分辨率权重贴图。如果预览时法线有明显接缝检查是否使用了 BlendAngleCorrectedNormals 节点。4. 实战案例二材质函数与材质层的高级组织当项目里出现多个材质共享同一套逻辑时继续复制粘贴节点行不通。UE5 提供了材质函数Material Function和材质层Material Layer两个工具专门解决材质逻辑复用和材质分层管理的问题。4.1 将复用逻辑封装为材质函数材质函数可以理解为“材质逻辑代码块”。它接受输入参数输出计算结果可以在任意材质中重复调用。比如刚才案例中的“两层材质混合”逻辑如果项目里有十几个模型都要用同样的双材质混合方式就应该封装成一个材质函数。创建方式很简单在 Content 目录右键选择Material旁边的Material Function选项新建后命名为MF_BlendTwoMaterials。打开材质函数编辑器在输入引脚位置添加自己需要的输入参数例如InputBaseColor A、BaseColor B、Normal A、Normal B、Roughness A、Roughness B、AlphaOutputBaseColor、Normal、Roughness在函数内部把三组 Lerp 和 BlendAngleCorrectedNormals 节点组织好将输出连接到 MaterialFunctionOutput 节点。保存后在其他材质中右键搜索这个函数名就可以像普通节点一样使用。材质函数带来的收益是明显的逻辑改动只需修改一处所有引用该函数的材质自动更新逻辑更清晰材质编辑器里不再堆满几十个节点也方便团队协作组长维护材质函数成员直接调用即可。4.2 材质层的概念与使用材质层是 UE5 中更高级的材质组织方式。它比材质函数更进一步把一个完整的材质“图层”打包成独立资产。材质层适合做多层混合材质比如地表包含草、岩石、泥土、雪四层每一层都可以独立创建为材质层资产然后在主材质中通过 Material Layer Blend 节点混合。创建材质层在 Content 目录右键选择Material展开子菜单选择Material Layer命名为ML_Grass和ML_Rock。打开材质层资产编辑方式和材质编辑器类似但注意材质层的输出不是直接接到最终材质输出而是连接到材质层的输出引脚例如 BaseColor、Normal、Roughness 等。在主材质中创建MaterialLayerBlend节点将多个材质层连接到不同的输入再设置一个混合权重来源。材质层的核心应用场景是 Landscape 地形材质。UE5 的 Landscape 材质中多层材质层通过权重贴图Layer Weight混合这是大型地形场景的标准做法。使用材质层能避免在同一个材质资产里堆叠几十个 Texture Sample让场景中地形材质性能可控。需要提醒的是材质层不是万能的它比普通材质略重使用前要评估场景需求。对于只有两层混合、简单重复逻辑的材质用材质函数就够了只有当面层数量多、需要单独维护每一层属性时材质层才是更优解。5. 不透明遮罩材质与阴影不实时变化的典型问题这是项目里大家反馈比较多的一个问题为模型制作“不透明遮罩材质”通过 Alpha 或遮罩纹理让模型表面某个区域透明例如做墙体从无到有的生长效果但阴影没有跟着实时变化。模型明明已经变得半透明或不透明了阴影却还是原来的完整形状非常影响效果。这个问题的本质和两种阴影渲染方式有关下面拆开分析。5.1 问题现象场景中有一个墙体模型材质使用了不透明遮罩方式Opacity Mask 通过一张噪声纹理或随时间变化的噪声来显示生长动画。运行时材质透明区域确实变化了但在接受 Shadow 的表面上阴影仍旧是墙体未剔除部分的状态没有体现遮罩导致的形状变化甚至出现阴影完整但材质透明区域不透明的情况。需要说明的是这里说的“不透明遮罩”指的是材质域设置为 Masked通过 Opacity Mask 引脚输出 0 或 1 控制像素是否显示它和 Translucent半透明是两种不同的透明实现方式。Opacity Mask 是 UE5 中做硬边透明效果的标准方法它支持阴影、支持 Nanite不产生半透明排序问题。Translucent 材质更复杂默认关闭阴影投射且无法参与深度写入不适合做生长效果。5.2 原因分析UE5 的阴影渲染会为每个 Mesh 生成阴影图。对于不透明物体阴影形状就是网格本身对于蒙版透明和半透明物体阴影系统需要额外知道自己哪部分透明。默认情况下UE5 的 Shadow Pass 会对材质执行一次简化版本的材质求值用 Opacity Mask 的结果来决定这个像素是否投射阴影。问题通常出现在以下几个环节第一材质输出节点中的 Opacity Mask 引脚没有正确连接实际遮罩节点或者连接的遮罩逻辑跟最终显示的不一致。第二项目的阴影模式使用了 Virtual Shadow Maps虚拟阴影贴图VSM时蒙版材质需要开启对应的“Masked”标识并且在 VSM 中阴影通道对蒙版材质的支持要求材质能够输出正确的 Opacity Mask。如果某个材质在 VSM 下阴影不更新要检查材质是否开启了“Cast Shadow” 相关的 Material 设置以及是否启用了正确的 Shading Model。第三这个效果是“随时间变化的”因此阴影也必须逐帧更新。动态阴影没问题但如果模型本身的阴影模式被设置为静态光源或使用了静态阴影那么阴影不会跟随材质动画变化就会产生“材质变了但阴影不变”的现象。第四材质中没有勾选Cast Shadow相关选项或者静态网格体的阴影设置被设置为 “Shadow Only” 或 “No Shadow”导致无法正确得到蒙版阴影。5.3 解决方案按下面的顺序逐项排查和修复。第一步确认材质域为 Masked而不是 Translucent。因为 Translucent 材质默认不支持投影阴影除非单独开启相关选项。第二步确认 Opacity Mask 引脚连接正确并设置合理的 Clip Value默认 0.333。只需把 Opacity Mask 当作一个二值开关大于 Clip Value 的像素显示小于的像素透明。测试时先用一个常量 0.5 或 0.0 分别测试确认 Mask 范围是否正常。第三步检查静态网格体的阴影设置。在 Actor 的 Details 面板中找到 Lighting 和 Cast Shadow 设置确认 Cast Shadow 已勾选。如果想要阴影跟随材质动画使用动态光源Movable Light并确认光源的阴影模式支持动态更新。第四步如果项目启用了 VSM确认材质在 Mesh 设置中没有被 Baked 阴影覆盖并且 VSM 的 Virtual Shadow Map 设置中允许 Masked 材质产生阴影。UE5 的 VSM 在渲染蒙版材质阴影时需要通过材质中的 Opacity Mask 结果作为阴影测试的 Alpha因此材质逻辑不能冗余到 Shadow Pass 无法识别。第五步如果材质使用了 World Position Offset 做生长动画阴影不变化也有可能是 WPO 没有被阴影 Pass 计算。需要开启材质设置中的Allow CPU Access或检查是否在材质设置中启用了Output Velocity确保阴影 Pass 能正确计算材质变形。对于类似“墙体生长”的动画推荐把 WPO 和 Opacity Mask 结合使用同时确认动画更新在阴影中生效。第六步也是容易忽略的一步如果模型使用了 NaniteNanite 网格对蒙版材质的阴影支持有限。Nanite 在绝大多数情况下不支持 Opacity Mask 材质如果遇到 Nanite 网格阴影不更新优先检查是否启用了 Nanite如果是把网格的 Nanite 支持关闭或使用 Nanite 的 PDOProgrammable Rasterization方案但该方案对材质的复杂度要求较高。简单来说蒙版材质阴影不实时变化多数情况不是引擎 bug而是阴影管线和材质域的配合问题。按照上面顺序排查基本都能定位到具体环节。6. 材质性能优化与移动端适配6.1 指令数与着色器复杂度UE5 材质编辑器顶部可以开启Shader Complexity预览模式。这个模式用颜色表示像素着色器的指令数绿色表示很轻红色表示极重。建议在开发阶段定期用这个模式检查场景中的材质尤其是大面积地表、植被和角色材质。指令数过高通常由以下原因造成贴图采样数量过多。每个 Texture Sample 都对应一次纹理采样移动端对纹理采样次数尤其敏感。使用了大量复杂数学函数比如 Sin、Cos、Noise 节点这些函数在移动端指令数较高。每个材质中都有复杂的分支逻辑Shader Compiler 可能展开所有分支导致指令膨胀。优化方向是移除不必要的 Texture Sample将多张单通道贴图打包到一张贴图的不同通道用材质函数抽离共用逻辑对于复杂的数学运算优先考虑预烘焙成贴图。6.2 纹理压缩与采样优化UE5 导入纹理时可以在纹理资产的 Compression Settings 中设置压缩格式。不同平台、不同纹理类型最佳压缩格式不同纹理类型推荐压缩格式说明BaseColorBC1 或 BC7BC7 质量最高体积最大NormalNormalMapBC5正确压缩法线精度单通道灰阶BC4适合 Roughness/AO/Metallic 单独使用UI 纹理不压缩或 BC7UI 纹理压缩容易出噪点纹理采样优化上注意以下几点第一避免让多个非平铺纹理在同一材质中共享同一 UV 空间可以拆成不同 UV 通道第二对于地表重复性纹理尽量使用可平铺贴图并用 Tile 参数控制重复次数减少贴图数量第三减少超大纹理的使用当前分辨率下 2K 通常够用4K 只在关键资产上使用。6.3 材质质量开关UE5 提供了 Feature Level Switch 和 Quality Switch 节点允许同一材质在不同环境下使用不同参数。例如移动端和 PC 端共用一个母材质时可以在 Roughness 或 Normal 输入前加入 Quality Switch让高画质使用完整法线贴图低画质使用扁平法线。这个方案能让项目的材质既满足高端 PC 的画质要求又不拖累移动端性能。开发阶段就要规划好不要等移植到移动端时再逐个改材质。7. 高频问题排查清单下面这张表整理了材质工作流中的高频问题方便遇到问题时快速排查。问题现象常见原因解决思路材质整体偏黑使用相同纹理所致的 UV 丢失或 Metallic 值过高检查 BaseColor 是否正常检查 Metallic 和 Roughness 参数法线贴图效果反了法线贴图未设置 NormalMap 压缩格式在纹理资产中修改 Compression Settings 为 NormalMap材质无法投影阴影材质域设置错误或网格 Cast Shadow 未勾选将材质改为 Masked开启网格的 Cast Shadow检查光源类型Masked 材质出现锯齿硬边Clip Value 阈值过低或贴图分辨率不足提高 Clip Value确保贴图有足够清晰度移动端材质报错使用了移动端不支持的节点或指令过多使用 Feature Level Switch 区分平台逻辑降低指令数材质实例参数无法调节母材质没有使用 Parameter 节点使用 ScalarParameter 或 VectorParameter 替代 Constant场景阴影闪烁阴影贴图分辨率不足或模式不受支持调整阴影设置或改用更稳定的动态阴影方案8. 最佳实践与工程建议材质工作流能否在团队中落地关键在于规范。下面几条是长期实践中沉淀下来的经验。第一建立统一的命名规范。材质用M_前缀贴图用T_前缀材质函数用MF_前缀材质层用ML_前缀参数集合用MPC_前缀。规范一旦定下来团队所有人保持一致查找资产时一眼就能定位。第二母材质尽量精简。母材质是逻辑的骨架不是参数的杂物间。每个母材质暴露的参数控制在 10 个以内超出部分考虑拆成多个材质实例或材质层。第三严格执行纹理优化流程。每张贴图导入项目前先确认尺寸、压缩格式、Mip 生成方式避免出现“临时导入、永远不优化”的情况。移动端尤其要控制纹理总数和贴图数量。第四材质分模块管理。把常用逻辑封装成材质函数比如“三层地表混合”“积雪覆盖”“边缘脏污”等。这样新成员接触项目时不需要从节点开始读而是直接调用函数项目交接效率大幅提升。第五性能检查要常态化。每次改动重要材质都切到 Shader Complexity 模式看一遍。不要等到美术资源全部进场后再做性能优化那时返工成本极高。第六针对特定问题单独做测试材质。如果某个效果无法判断问题原因单独创建一个纯色材质或最小化节点材质来定位。这个习惯能减少大量排查时间。9. 总结与进阶路径到这UE5 材质大师班的下半部分就完整了。从 PBR 参数体系回顾到材质工作流拆解再到地表混合材质、材质函数、材质层的实战案例最终落地到蒙版阴影问题和性能优化这一整套内容基本覆盖了 UE5 材质工作中最核心、最常踩坑的部分。接下来可以继续深入的方向很明确如果做大型场景重点研究 UE5 Landscape 的地形材质分层和 Runtime Virtual TextureRVT这是大世界地表的标准方案如果做角色可以考虑学习 Subsurface Profile 和布料着色模型把皮肤、布料材质做细如果想走技术美术路线可以学习 HLSL 自定义节点直接在材质里写更复杂的着色器逻辑。不管往哪个方向深入建议始终带着两个习惯一是坚持用工作流思维管理材质而不是每次临时拼节点二是严格要求性能指标把 Shader Complexity 当成日常开发的一部分。材质本身不难难的是在真实项目中持续产出稳定、高效、可维护的材质资产。
返回列表