总结1、先在对应ShadingModel注册对应的pin输入2、修改在ShadingModel注册对应的pin输入名称3、增加GBuffer数据CustomMask4、将CustomMask的数据给到GBuffer.CustomMask5、将GBuffer.CustomMask的数据给到GBufferD.a6、隔离与其他ShadingModel情况下GBuffer.CustomMask值的影响第一步让 Default Lit 材质显示一个 Custom Mask 输入文件[Material.cpp (line 7879)](D:/UnrealEngine-release/UnrealEngine-release/Engine/Source/Runtime/Engine/Private/Materials/Material.cpp:7879)找到case MP_CustomData0: Active ShadingModels.HasAnyShadingModel({ MSM_ClearCoat, MSM_Hair, MSM_Cloth, MSM_Eye, MSM_SubsurfaceProfile }); break;改成case MP_CustomData0: Active ShadingModels.HasAnyShadingModel({ MSM_DefaultLit, MSM_ClearCoat, MSM_Hair, MSM_Cloth, MSM_Eye, MSM_SubsurfaceProfile }); break;写了这句话相当于你选择ShadingModel为MSM_DefaultLit后CustomData0这个输入接口会从灰变亮并可以正确输入数据进里面然后改显示名字。文件[MaterialAttributeDefinitionMap.cpp (line 490)](D:/UnrealEngine-release/UnrealEngine-release/Engine/Source/Runtime/Engine/Private/Materials/MaterialAttributeDefinitionMap.cpp:490)找到case MP_CustomData0: CustomPinNames.Add({ MSM_ClearCoat, LOCTEXT(ClearCoat, Clear Coat).ToString() });在下面加一行case MP_CustomData0: CustomPinNames.Add({ MSM_DefaultLit, LOCTEXT(CustomMask, Custom Mask).ToString() }); CustomPinNames.Add({ MSM_ClearCoat, LOCTEXT(ClearCoat, Clear Coat).ToString() }加上这一行原来ShadingModel为DefaultLit的情况下名字应该为CustomData0变成名字为CustomMask第二步给 GBuffer 数据结构加一个逻辑字段文件[DeferredShadingCommon.ush (line 335)](D:/UnrealEngine-release/UnrealEngine-release/Engine/Shaders/Private/DeferredShadingCommon.ush:335)在FGBufferData里找到// 0..1 float4 CustomData;后面加// 0..1, user-defined mask stored in GBufferD.a for DefaultLit materials. half CustomMask;意思这不是新增一张 GBuffer 纹理只是在 shader 解码后的结构体里多一个字段方便后续 shader 用GBuffer.CustomMask读取。第三步BasePass 阶段从材质读取 Mask文件[ShadingModelsMaterial.ush (line 12)](D:/UnrealEngine-release/UnrealEngine-release/Engine/Shaders/Private/ShadingModelsMaterial.ush:12)在SetGBufferForShadingModel(...)里找到GBuffer.ShadingModelID ShadingModel;后面加#if MATERIAL_SHADINGMODEL_DEFAULT_LIT if (ShadingModel SHADINGMODELID_DEFAULT_LIT) { GBuffer.CustomMask saturate(GetMaterialCustomData0(PixelMaterialInputs)); } #endif意思GetMaterialCustomData0(PixelMaterialInputs)读取你在材质节点上接入的Custom Mask值。第四步把 Mask 真正写进 GBufferD.a文件[DeferredShadingCommon.ush (line 879)](D:/UnrealEngine-release/UnrealEngine-release/Engine/Shaders/Private/DeferredShadingCommon.ush:879)在EncodeGBuffer(...)里找到OutGBufferD GBuffer.CustomData; OutGBufferE GBuffer.PrecomputedShadowFactors;改成OutGBufferD GBuffer.CustomData; if (GBuffer.ShadingModelID SHADINGMODELID_DEFAULT_LIT) { OutGBufferD.a GBuffer.CustomMask; } OutGBufferE GBuffer.PrecomputedShadowFactors;意思GBufferD仍然整体来自CustomData但当材质是 Default Lit 时我们把 alpha 通道改成自己的CustomMask。这样不会影响 ClearCoat、Cloth、Eye 等特殊 shading model 的CustomData.a。第五步Deferred 阶段从 GBufferD.a 解码回来同一个文件[DeferredShadingCommon.ush (line 987)](D:/UnrealEngine-release/UnrealEngine-release/Engine/Shaders/Private/DeferredShadingCommon.ush:987)在DecodeGBufferData(...)里找到GBuffer.CustomData HasCustomGBufferData(GBuffer.ShadingModelID) ? InGBufferD : 0;后面加GBuffer.CustomMask (GBuffer.ShadingModelID SHADINGMODELID_DEFAULT_LIT) ? InGBufferD.a : 0;意思只有 Default Lit 才把GBufferD.a解释成你的自定义 Mask其他 shading model 返回 0避免语义混乱。第六步使用这个 Mask例如想影响 Default Lit 光照可以去这个文件[ShadingModels.ush (line 203)](D:/UnrealEngine-release/UnrealEngine-release/Engine/Shaders/Private/ShadingModels.ush:203)在DefaultLitBxDF(...)里光照算完之后、return Lighting;之前可以先临时加Lighting.Diffuse * lerp(1.0f, 0.2f, GBuffer.CustomMask);意思CustomMask 0时不影响漫反射CustomMask 1时漫反射压暗到 20%。这只是验证用。确认链路通了之后你可以改成描边、湿润度、受击高亮、特殊材质分类等效果。改完后需要重新编译 C因为前两步改了材质编辑器/材质属性逻辑shader 改动则需要重新编译 shader。材质里建一个 Scalar Parameter 叫CustomMask接到 Default Lit 材质节点上新显示的Custom Maskpin调 0 到 1 就能验证。结果