# 参考文章 UE4版本:https://zhuanlan.zhihu.com/p/446587397 # c++部分 ## 添加ShaderModel - EngineType.h 在EMaterialShadingModel中添加ShaderModel枚举 ## 添加材质编辑器引脚 - SceneTypes.h 在EMaterialProperty中添加2个引脚属性名称枚举。 - Material.h 在UMaterial类中添加FScalarMaterialInput类型变量CustomData2与CustomData3。 ### MaterialExpressions.cpp - 给MakeMaterialAttributes节点增加对应引脚: - 添加CustomData2与CustomData3声明。(位于MaterialExpressionMakeMaterialAttributes.h) - 修改UMaterialExpressionMakeMaterialAttributes::Compile(),增加CustomData2与CustomData3的对应列。 - 给BreakMaterialAttributes节点增加对应引脚: - 修改UMaterialExpressionBreakMaterialAttributes::UMaterialExpressionBreakMaterialAttributes(),增加CustomData2与CustomData3的对应列。 - 修改UMaterialExpressionBreakMaterialAttributes::Serialize(),增加两列`Outputs[OutputIndex].SetMask(1, 1, 0, 0, 0); ++OutputIndex;` - 修改BuildPropertyToIOIndexMap(),增加CustomData2与CustomData3的对应列,并且将最后一行的index改成合适的数值。 - 修改断言条件`static_assert(MP_MAX == 32`=>`static_assert(MP_MAX == 34` ### MaterialShared.cpp - 修改FMaterialAttributeDefinitionMap::InitializeAttributeMap(),给CustomData2与CustomData3添加对应码,只需与之前的不重复即可。 - 修改FMaterialAttributeDefinitionMap::GetAttributeOverrideForMaterial(),修改新添加的ShaderModel的引脚在材质编辑器中的显示名称。 ### MaterialShader.cpp - 修改GetShadingModelString(),给新增加的ShaderModel添加返回字符串。 - 修改UpdateMaterialShaderCompilingStats(),给性能统计添加新增加的ShaderModel条件判断,`else if (ShadingModels.HasAnyShadingModel({ MSM_DefaultLit, MSM_Subsurface, MSM_PreintegratedSkin, MSM_ClearCoat, MSM_Cloth, MSM_SubsurfaceProfile, MSM_TwoSidedFoliage, MSM_SingleLayerWater, MSM_ThinTranslucent ,MSM_NPRShading}))` ### Material.cpp - 修改UMaterial::PostLoad(),给新增加的引脚添加对应的两行代码,来对材质属性进行重新排序,`DoMaterialAttributeReorder(&CustomData2, UE4Ver, RenderObjVer);` - 修改UMaterial::GetExpressionInputForProperty(),给新增加的引脚添加对应的两行代码。 - 修改UMaterial::CompilePropertyEx(),给新增加的引脚添加对应的两行代码。编译材质属性。 - 修改static bool IsPropertyActive_Internal(),控制材质编辑器中引脚是否开启。给CustomData添加对应的代码。 ### HLSLMaterialTranslator.cpp 控制材质节点编译(拼接)成完整的ShaderCode。 - 修改FHLSLMaterialTranslator::FHLSLMaterialTranslator(),给SharedPixelProperties数组中引脚对应index赋值为true。 - 修改FHLSLMaterialTranslator::GetMaterialEnvironment(),给新增加的ShaderModel添加宏。 - 修改FHLSLMaterialTranslator::GetMaterialShaderCode()。给新增加的引脚添加对应的两行`LazyPrintf.PushParam(*GenerateFunctionCode(MP_CustomData1));`。该函数会读取`/Engine/Private/MaterialTemplate.ush`并对替换字符格式化。 - 修改FHLSLMaterialTranslator::Translate(),为新增加的两个引脚增加两行: ```c# Chunk[MP_CustomData2] = Material->CompilePropertyAndSetMaterialProperty(MP_CustomData2 ,this);//NPR Shading Chunk[MP_CustomData3] = Material->CompilePropertyAndSetMaterialProperty(MP_CustomData3 ,this); ``` ### MaterialGraph.cpp 材质界面代码。修改UMaterialGraph::RebuildGraph(),用来显示新添加的两个引脚: ```c# MaterialInputs.Add( FMaterialInputInfo(FMaterialAttributeDefinitionMap::GetDisplayNameForMaterial(MP_CustomData2, Material), MP_CustomData2, FMaterialAttributeDefinitionMap::GetDisplayNameForMaterial(MP_CustomData2, Material))); MaterialInputs.Add( FMaterialInputInfo(FMaterialAttributeDefinitionMap::GetDisplayNameForMaterial(MP_CustomData3, Material), MP_CustomData3, FMaterialAttributeDefinitionMap::GetDisplayNameForMaterial(MP_CustomData3, Material))); ``` ### 解决添加引脚后 添加引脚后会出现`PropertyConnectedBitmask cannot contain entire EMaterialProperty enumeration.`的编译错误。需要将 ```c# uint32 PropertyConnectedBitmask; ``` =》 ```c# uint64 PropertyConnectedBitmask; ``` 再将函数中的转换类型改成uint64即可。 ```c# ENGINE_API bool IsConnected(EMaterialProperty Property) { return ((PropertyConnectedBitmask >> (uint64)Property) & 0x1) != 0; } ENGINE_API void SetConnectedProperty(EMaterialProperty Property, bool bIsConnected) { PropertyConnectedBitmask = bIsConnected ? PropertyConnectedBitmask | (1i64 << (uint64)Property) : PropertyConnectedBitmask & ~(1i64 << (uint64)Property); } ``` # Shader部分 ## MaterialTemplate.ush 给新增加的引脚增加对应的格式化代码: ```c# half GetMaterialCustomData2(FMaterialPixelParameters Parameters) { %s; } half GetMaterialCustomData3(FMaterialPixelParameters Parameters) { %s; } ``` ## ShadingCommon.ush - 新增加的ShaderModel添加ID宏,`#define SHADINGMODELID_NPRSHADING 12` - 修改float3 GetShadingModelColor(uint ShadingModelID),给添加的ShaderModel设置一个显示颜色。 ## BasePassCommon.ush - 修改#define WRITES_CUSTOMDATA_TO_GBUFFER宏,在最后的条件判断中添加新增加的ShaderModel。 ## DeferredShadingCommon.ush - 修改bool HasCustomGBufferData(int ShadingModelID),在条件判断中添加新增加的ShaderModel。 ## ShadingModelsMaterial.ush - 修改void SetGBufferForShadingModel(),该函数用于设置输出的GBuffer,给新增加的ShaderModel添加对应的代码段: ```c# #ifdef MATERIAL_SHADINGMODEL_NPRSHADING else if(ShadingModel == SHADINGMODELID_NPRSHADING) { GBuffer.CustomData.x=saturate(GetMaterialCustomData0(MaterialParameters)); GBuffer.CustomData.y=saturate(GetMaterialCustomData1(MaterialParameters)); GBuffer.CustomData.z=saturate(GetMaterialCustomData2(MaterialParameters)); GBuffer.CustomData.w=saturate(GetMaterialCustomData3(MaterialParameters)); } #endif ``` ## 光照实现 - ShadingModel.ush,BxDF实现。 - DeferredLightingCommon.ush,延迟光照实现。 # UE5版本 - 5.2 https://zhuanlan.zhihu.com/p/658700282 - 5.1 https://zhuanlan.zhihu.com/p/565837897 # 相关文件 - UMaterialInterface、UMaterial、UMaterialInstance、FMaterial、FMaterialResource、FMateialRenderProxy、FMaterialInstanceResource、FDefaultMaterialInstance - MaterialShader.cpp - HLSLMaterialTranslator.cpp - MaterialHLSLEmitter:塞入ShaderModel宏 - Material.cpp:开启引脚 - MaterialAttributeDefinitionMap.cpp - ShaderMaterialDerivedHelpers.cpp - ShaderGenerationUtil.cpp - ShadingCommon.ush # Material编辑器相关代码 - FMaterialInstanceBasePropertyOverrides - FMaterialInstanceParameterDetails https://zhuanlan.zhihu.com/p/565776677 https://www.cnblogs.com/timlly/p/15109132.html