资讯动态

Substrate材质迁移:彻底搞懂Metalness到DiffuseAlbedo/F0转换节点

发布时间:2026/10/13 15:05:44 来源:尧图企业网站定制
上个月帮朋友迁移一个演示工程引擎从老版本一路升到带Substrate的版本。打开插件后我第一件事就是想把那套用了很久的传统金属材质换到新材质流程里。结果材质编辑器打开的一瞬间我猜谁都一样原来那一排BaseColor、Metallic、Specular、Roughness滑条全没了取而代之的是一棵参数树以及一堆看起来更底层的参数名。我盯着DiffuseAlbedo和F0看了半天心想“这俩以前不是藏在Metallic后面吗”。后来把Metalness-To-DiffuseAlbedo-F0这个节点用顺手了才意识到这次迁移不是简单换个节点而是整个材质参数体系在换骨架。这篇文章就把这个节点彻底讲透。适合正在做Substrate迁移的技术美术、材质美术以及想弄明白旧PBR和新PBR参数映射关系的图形程序员。1. 第一次启用Substrate时材质编辑器里消失的Metalness滑条1.1 打开老材质后的第一轮混乱用传统材质模型写了三五年材质的TA第一次打开Substrate的材质编辑器大概率会愣一下。原来的Shading Model下拉菜单、Metallic滑条、Specular滑条、Roughness滑条真的一个都不在了。取而代之的是一大块新的节点类型比如Substrate Material、Substrate Mixed Material、Substrate Layered Material。你在旧材质里建的节点最终输出是Material Attributes到了Substrate最终输出变成了一棵树树根是一个Slab节点的参数列表里面直接写着DiffuseAlbedo、F0、Roughness这些名字。我一开始以为只是改版后把参数收纳进了一个结构体于是熟门熟路地把老的BaseColor贴图往树里的DiffuseAlbedo一拖再把旧的Metallic贴图到处找地方塞。结果发现在这个新体系里根本没有名为Metallic的输入位。你按TAB搜索也搜不到金属度这个关键词能搜到的只有一堆“Metalness To xxx”之类的转换工具节点。换句话说不只是参数位置变了而是底层材质模型默认不再使用金属度作为核心输入了。那一瞬间我是慌的。因为工程里的资产几百个不可能指望美术团队把每张贴图重画一遍。这也是Substrate必须提供各种转换节点的原因而所有这些转换节点的起点就是名字又长又绕的Metalness-To-DiffuseAlbedo-F0。1.2 一个名字很长的过渡节点为什么值得单独讲这个节点的名字已经把它做的事写完了把传统PBR材质里的Metalness转换成Substrate需要的DiffuseAlbedo和F0。不同引擎版本的节点命名可能有一点点差别比如显示成Metalness To DiffuseAlbedo F0或者Metalness-To-DiffuseAlbedo-F0但功能基本一致。为什么值得单独拿出来讲一整篇因为所有从旧材质迁移到Substrate的资产几乎都要经过它。它看起来像是一个傻瓜式转换器接上贴图就能出结果但我在实际项目里见过太多次错误用法有人把输出F0当成旧的高光强度再乘一次系数有人把Metalness贴图留在sRGB空间导致过渡区域脏成一片还有人完全没搞懂DiffuseAlbedo到底该接到哪个Slab端口。这些错误如果不懂节点内部的参数语义光靠眼睛看渲染结果是很难定位的。所以这篇文章的核心不是教你“把A接到B”而是把节点输入输出背后的物理含义和数学关系彻底拆开这样你才能判断自己的接线是不是真的正确。2. 传统PBR为什么需要MetalnessBaseColor一通道承担两种物理身份2.1 非金属和金属在物理上本来就是两个独立的东西要理解为什么Substrate要把Metalness消解掉首先要回到物理层面。非金属也就是电介质比如木头、塑料、皮肤、混凝土它们的光学行为是光进入表面后发生折射、散射部分光再从表面逸出表现为漫反射颜色。它们表面的菲涅尔反射率F0非常低通常在0.02到0.08之间而且是近似无色的灰最多带一点点色相偏移。金属则完全不同。金属是导体表层自由电子会立即吸收入射光并重新辐射出去所以金属几乎没有体漫反射它的反射色直接就是材料本身的“颜色”。铜是暖橙色的高反射金是黄绿色调的高反射铝接近中性白高反射。金属的F0可以高得多常在0.5到1.0之间而且F0本身就是RGB彩色。这里可以用一个简单公式理解F0的来源。对于垂直入射的光F0大体可以由折射率n推算出来F0 ((n - 1) / (n 1))^2几种常见材料的F0水大约是0.02玻璃大约0.04树脂塑料大约0.04到0.05钻石因为折射率高能到0.17以上。这就是为什么传统PBR里非金属的高光永远不应该是纯白或者纯黑而是一个非常暗的灰。物理世界已经把范围框死了。金属的漫反射反照率在理论上接近零因为光根本没有机会进入金属内部发生体散射。这也是为什么金属材质的Albedo贴图画成深色是合理的但如果你把一个金属物件的高光反射色画进BaseColor里的“漫反射”部分那就彻底混乱了。2.2 Metalness把两类参数缝进一条通道也留了一个隐患传统PBR为了解决成本问题发明了Metalness这个标量。它本质上是一个分类开关0代表非金属1代表金属中间值在物理上并不真实存在。美术拿一张BaseColor贴图同时承担两个身份当Metalness为0时BaseColor是漫反射颜色当Metalness为1时BaseColor是F0反射颜色。于是就有了经典近似映射diffuseAlbedo BaseColor * (1 - Metalness) F0 lerp(f0NonMetal, BaseColor, Metalness)其中f0NonMetal来自旧的Specular参数默认0.5。而引擎光照模型内部再做一次混合把漫反射结果和镜面反射结果按Metalness权重混合起来。这个设计在资源上是省了一件大事一张BaseColor贴图同时记录非金属的固有色和金属的反射色不需要为金属区域单独画一张F0贴图也不需要为金属材质单独准备一套漫反射贴图。但隐患也随之而来。美术在画贴图时必须心知肚明这个笔刷画出来的深色锈迹在金属区域会被当作反射色在非金属区域会被当作体色同一个数值在不同材质语义下结果天差地别。尤其是很多游戏项目喜欢用“金属、非金属混合在一张贴图”的办法做旧化比如金属表面有漆面剥落、有灰尘、有锈迹这时候BaseColor里的某块颜色到底是漫反射还是F0就成了一笔糊涂账。传统工作流里这个账靠美术的经验在记到了Substrate你就需要一个显式工具把这笔账重新拆开。3. 参数重构后的Substrate为什么容不下Metalness桥接节点的设计动机3.1 Slab体系里的DiffuseAlbedo和F0是独立参数Substrate和传统材质节点最大的差别不是换了个皮肤而是把材质从“一个输入面板一个固定Shading Model”变成了“用Slab节点组合出来的材质树”。简单理解Slab可以看作一个材质参数块。一个常规的Substrate材质至少有一个BSDF SlabBSDF Slab里直接提供DiffuseAlbedo、F0、Roughness等输入。如果你要做多层混合材质就再叠一个Mixed或Layered Slab不同层各自有自己的BSDF参数。编辑器里呈现的就是一棵参数树树的每根分支都对应一个物理属性块。在这个体系里没有Metallic滑条的位置。因为Metalness的本质不是一个物理属性而是“把漫反射参数和镜面反射参数二选一”的包装器。Substrate选择了更底层、更接近物理的语言它直接问你两个问题漫反射颜色是多少垂直反射率F0是多少所以老资产进入到新体系必须有一个翻译过程把二选一的包装打开把其中一部分信息放到DiffuseAlbedo另一部分放到F0。Metalness-To-DiffuseAlbedo-F0节点就是这个翻译器。3.2 分离之后多层混合的收益才真正体现为什么这个转换值得做而不是继续保留金属度我在实际做多层材质测试时感受很深。传统材质做多层混合最常见的结果是两层都要输出一张“BaseColorMetalness”的组合在混合节点里再按遮罩插值。这里有一个隐藏问题金属度是标量插值但BaseColor的语义在两层里可能完全不同。上层是掉漆的铁板下层是红锈两层各自有Metalness插值过程中红锈区的反射特性和铁板的反射特性会交叉污染。你很难在着色器层面精确控制“这一层混入多少Marble、那一层保留多少Metalness”。Substrate把每层的DiffuseAlbedo和F0拆开之后层与层之间可以做到更干净的物理叠加。每个BSDF Slab自己就是一个完整的反射模型层之间的混合是BSDF层的混合不是参数表中四个滑条的混合。这个优势的前提是老材质的参数先被正确地拆解到DiffuseAlbedo和F0里。如果拆错了层叠后会出现更诡异的结果。所以说Metalness-To-DiffuseAlbedo-F0不只是为了迁移兼容而存在的补丁节点它是整个Substrate材质树里物理正确性的第一道入口。4. 输入输出与内部映射一份可以手推的公式4.1 输入端与输出端的语义区别这个节点通常有三个输入端、两个输出端端口来源语义注意点BaseColor旧BaseColor贴图同时包含旧漫反射色和旧金属反射色贴图存储空间是sRGB进入材质网络后按线性计算Metalness旧Metallic贴图材质区域分类非金属0金属1必须是线性数据纹理属性里关掉sRGBSpecular旧Specular参数常为0.5非金属区域的F0微调不是高光强度是反射率微调DiffuseAlbedo输出去往Substrate Slab漫反射反照率非金属区域有效金属区域接近0F0输出去往Substrate Slab垂直入射菲涅尔反射率旧金属色从这里回到光照系统特别注意一点Roughness不经过这个节点。老材质里的Roughness贴图仍然直接连到Substrate Slab的Roughness端口不要等这个节点帮你传。转换节点只处理BaseColor和Metalness之间的参数重分配。4.2 节点的核心映射公式根据经典PBR近似节点内部做的核心映射可以写成这样diffuseAlbedo BaseColor * (1 - Metalness) F0 lerp(f0NonMetal, BaseColor, Metalness)其中f0NonMetal是旧Specular映射过来的非金属反射率。在传统UE材质里默认Specular0.5对应的非金属F0大约落在0.04到0.08这个区间。0.04对应折射率1.5左右的典型玻璃/树脂0.08则更接近很多引擎默认采用的美术化反射基准。具体映射系数在Substrate各版本之间可能略有差异因为有的版本还做了能量补偿或色彩空间修正但大方向就是这个。这个公式解释了不少问题。当Metalness为0整个BaseColor原封不动进入DiffuseAlbedoF0是一个接近灰0.04的小值这就是一块标准非金属。当Metalness为1DiffuseAlbedo被乘成0BaseColor整体进入F0这就是一块纯金属。中间值则是不伦不类的“半金属”物理上不存在传统工作流里也不应该出现。旧式Specular滑条的作用也在公式里体现了。它不是直接调高光亮度而是调非金属区域的F0基准值。Specular越高非金属的高光反射率越高。到了Substrate体系这个值最终映射成F0输出不要再额外乘0.04或者加0.08否则反射亮度会错得离谱。4.3 三组手算样例从0到1暴力验证我们设BaseColor为红色常量(0.8, 0.1, 0.1)Specular保持默认0.5Metalness分别取0、0.6、1。手工算一下输出Metalness值DiffuseAlbedo输出F0输出实际含义0(0.8, 0.1, 0.1)灰色小值大约0.04左右红色塑料/油漆表面0.6(0.32, 0.04, 0.04)从灰0.04向红(0.8,0.1,0.1)插值60%半金属过渡通常应避免1(0, 0, 0)(0.8, 0.1, 0.1)红色金属例如红铜这个表建议你保存下来后面做材质调试时可以直接对照。我自己调试时经常用纯色常量而不是真实贴图就是为了快速验证节点逻辑是否按预期工作。如果渲染出来的金属区域高光颜色不是BaseColor的值反而整体发灰大概率是F0链路被改过。在真实项目里我几乎不会主动使用0.6这种金属度中间值。旧材质如果有这种中间值一般都应该检查是不是贴图没画干净而不是指望Substrate帮你“修正”成一个真实材质。5. 老材质迁移接线顺序以及三个让我返工的接线坑5.1 标准接线顺序从贴图到Substrate Slab如果你只是想把一个老材质快速迁到Substrate可以按这个顺序操作启用Substrate插件重启编辑器。新建一个Substrate Material节点双击进入内部结构找到Substrate Slab参数块。把旧材质里的BaseColor纹理接到转换节点的BaseColor输入Metallic纹理接到Metalness输入Specular常数或贴图接到Specular输入。把转换节点的DiffuseAlbedo输出和F0输出分别接到Substrate Slab对应的DiffuseAlbedo和F0端口。旧Roughness贴图直接接到Slab的Roughness端口。编译保存先不急着调参数跑一帧看整体亮度趋势。大致框图不需要复杂化本质上就是把旧材质面板上的三个参数搬运到转换节点三个输入端再把两个输出接到新Slab对应的两个端口。不同引擎版本里Slab端口的名字可能有细微差别比如有的版本叫Base Color有的版本叫Diffuse Albedo但物理语义一致以你当前编辑器显示的引脚为准。5.2 坑一F0输出被当成旧高光强度二次缩放这个坑我至少见三个人踩过。一些美术在传统材质里习惯了“Specular滑条控制高光强度”这种潜意识看到F0输出就以为是高光强度顺手把它接到新材质的高光参数或者乘了一个0.04再进Slab结果金属材质的高光弱到几乎看不见。F0不是高光强度它是垂直入射时的菲涅尔反射率是PBR模型的直接输入。金属区域的F0就是金属的反射颜色比如红铜的F0接近它本身的暖红色。如果你在节点后端乘0.04等于把红铜的反射率压到了玻璃级别金属感直接消失。正确做法是转换节点输出什么就把什么原样送到Slab中间不要再乘任何权重。如果你想把F0接到材质树上某个自定义复数颜色端口也请先确认那个端口的语义是线性反射率而不是“亮度增益”。5.3 坑二Metalness贴图被留在sRGB空间有个项目迁移后金属边缘总出现一条又脏又亮的过渡带怎么调高光参数都没用。我排查到贴图才发现项目的Metalness贴图在纹理导入设置里勾着sRGB也就是说它被当成了颜色贴图进到节点前先被转到了线性空间数值曲线被拉变形。金属度贴图在传统工作流里必须按线性数据处理。如果它被视作sRGB原本0和1之间的阶跃边缘就会带上中间渐晕转换节点拿到一个错误的0.5最终生成一个不存在的半金属区域。检查方法是直接看纹理导入面板确认颜色空间那一栏是“线性数据不勾选sRGB”。还有一个小验证办法把Metallic贴图临时替换成一个纯常量0或1如果过渡脏边消失说明问题就是贴图空间设置而不是光照模型本身。5.4 坑三多层材质时所有层都接到了同一个Slab上再上升到复合材质时问题会更隐蔽。Substrate做多层混合时不是把所有贴图接到同一个材质结果节点而是使用Mixed或Layered材质每层有自己的Slab实例。有些人在转换时图省事把顶层和底层的贴图全部连到同一个Slab上再靠遮罩混合结果层与层之间没有任何遮挡裁剪透光、混色、高光叠影全来了。正确做法是每种语义的层单独走一遍转换节点各自的DiffuseAlbedo和F0送进对应Slab。比如做掉漆金属板底层是铁锈层顶层是金属漆层两层要各自构建两个BSDF实例层间混合交给Substrate的层叠机制而不是把所有参数揉进一个BSDF。这样F0才能正确参与层间插值而不是被错误的线性混合冲掉。6. 用极端颜色验证转换结果边界检查与反向换算6.1 纯色极限测试金属与非金属必须界限分明迁移完一批材质不能只看场景截图就下结论。我的建议是做一个专门的纯色测试材质用常量代替贴图把BaseColor固定成明显红色Metalness分别改成0和1编译后渲染到测试小球上。观察两个关键点非金属球的高光应该非常暗且近似无色金属球的高光/反射应该呈现明显红色而且漫反射几乎消失。如果你觉得暗部差异看不清可以把F0或者DiffuseAlbedo临时接到Emmisive输出口再乘一个50到100的系数用自发光放大暗部差异。这样你就能直观看到0.04这样的灰值和金属色的区别不用靠猜。我经常看到有人在这步发现节点反转的严重问题非金属变成了强高光的亮片金属反而变成哑光红塑料。出现这种结果先检查输入贴图颜色空间再检查F0链路是否被二次修改最后检查BaseColor贴图是不是被美术画成了平面光照效果而非线性颜色。6.2 反向换算与批量迁移时的高效验证Substrate体系里还存在着与这个转换节点方向相反的工具作用是把DiffuseAlbedo和F0合并回Metalness用于在传统和Substrate之间往返转换。我建议你至少手动验证一次“正向转换再反向转换”的误差范围确认你用的引擎版本在这个链路上没有引入奇怪的偏移。做法很简单用转换节点把老材质转成Substrate参数再用反向节点把DiffuseAlbedo和F0并回BaseColor和Metalness对比最初值。如果数值误差在可忽略范围内说明迁移链路是健康的。如果黑点或高光区域误差明显多半是贴图色彩空间或者Specular映射系数与版本默认值不符需要单独处理。批量迁移时不需要每个材质都做细致的视觉对比。抽三层级做往返验证外加所有资产做纯色极限测试就足够了。真正费时间的地方是那些“金属与非金属混杂在BaseColor里”的旧资产它们转换后很可能出现中间金属度需要美术按区域重新归类贴图而不是靠节点救回来。我自己真正吃透这个节点后最大的变化不是学会了某个操作而是重新理解了传统PBR工作流的取舍。Metalness是美术便利和资产成本妥协出来的产物而Substrate想走的是物理参数独立的路子。转换节点就是这个过渡期的翻译官它把旧账拆开重记虽然第一眼看过去有点吓人但用顺了你就会发现参数语义清楚了很多以前说不清的高光问题都不用再猜。如果你也在做迁移我建议把本文这个映射公式贴到项目Wiki里并且固定好Metalness贴图的线性空间规范。别只靠节点名字去猜协议不然迟早会在某个多层材质上翻车。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑