UE 添加自定义着色模型
1. 在 EngineTypes.h 中添加新的模型枚举
假设新的模型名称为 MercuryToon
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
UENUM()
enum EMaterialShadingModel : int
{
MSM_Unlit UMETA(DisplayName="Unlit"),
MSM_DefaultLit UMETA(DisplayName="Default Lit"),
MSM_Subsurface UMETA(DisplayName="Subsurface"),
MSM_PreintegratedSkin UMETA(DisplayName="Preintegrated Skin"),
MSM_ClearCoat UMETA(DisplayName="Clear Coat"),
MSM_SubsurfaceProfile UMETA(DisplayName="Subsurface Profile"),
MSM_TwoSidedFoliage UMETA(DisplayName="Two Sided Foliage"),
MSM_Hair UMETA(DisplayName="Hair"),
MSM_Cloth UMETA(DisplayName="Cloth"),
MSM_Eye UMETA(DisplayName="Eye"),
MSM_SingleLayerWater UMETA(DisplayName="SingleLayerWater"),
MSM_ThinTranslucent UMETA(DisplayName="Thin Translucent"),
MSM_Strata UMETA(DisplayName="Substrate", Hidden),
// BEGIN Engine Change [Shading Model]: Adding a new shading model enum
MSM_MercuryToon UMETA(DisplayName="MercuryToon"),
// END Engine Change
/** Number of unique shading models. */
MSM_NUM UMETA(Hidden),
/** Shading model will be determined by the Material Expression Graph,
by utilizing the 'Shading Model' MaterialAttribute output pin. */
MSM_FromMaterialExpression UMETA(DisplayName="From Material Expression"),
MSM_MAX
};
2. 在 MaterialExpressionShadingModel.h 中添加新的模型枚举选项
在 UPROPERTY 中添加 MSM_MercuryToon
1
2
UPROPERTY(EditAnywhere, Category=ShadingModel, meta=(ValidEnumValues="MSM_DefaultLit, MSM_Subsurface, MSM_PreintegratedSkin, MSM_ClearCoat, MSM_SubsurfaceProfile, MSM_TwoSidedFoliage, MSM_Hair, MSM_Cloth, MSM_Eye, MSM_MercuryToon", ShowAsInputPin = "Primary"))
TEnumAsByte<enum EMaterialShadingModel> ShadingModel = MSM_DefaultLit;
3. 在 MaterialShader.cpp 中添加着色模型到字符串的转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/** Converts an EMaterialShadingModel to a string description. */
FString GetShadingModelString(EMaterialShadingModel ShadingModel)
{
FString ShadingModelName;
switch(ShadingModel)
{ case MSM_Unlit: ShadingModelName = TEXT("MSM_Unlit"); break;
case MSM_DefaultLit: ShadingModelName = TEXT("MSM_DefaultLit"); break;
case MSM_Subsurface: ShadingModelName = TEXT("MSM_Subsurface"); break;
case MSM_PreintegratedSkin: ShadingModelName = TEXT("MSM_PreintegratedSkin"); break;
case MSM_ClearCoat: ShadingModelName = TEXT("MSM_ClearCoat"); break;
case MSM_SubsurfaceProfile: ShadingModelName = TEXT("MSM_SubsurfaceProfile"); break;
case MSM_TwoSidedFoliage: ShadingModelName = TEXT("MSM_TwoSidedFoliage"); break;
case MSM_Hair: ShadingModelName = TEXT("MSM_Hair"); break;
case MSM_Cloth: ShadingModelName = TEXT("MSM_Cloth"); break;
case MSM_Eye: ShadingModelName = TEXT("MSM_Eye"); break;
case MSM_SingleLayerWater: ShadingModelName = TEXT("MSM_SingleLayerWater"); break;
case MSM_ThinTranslucent: ShadingModelName = TEXT("MSM_ThinTranslucent"); break;
// Mercury Toon Begin
case MSM_MercuryToon: ShadingModelName = TEXT("MSM_MercuryToon"); break;
// Mercury Toon End
default: ShadingModelName = TEXT("Unknown"); break;
} return ShadingModelName;
}
4. 在 MaterialShader.cpp 将着色模型设置为光照(Lit)模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void UpdateMaterialShaderCompilingStats(const FMaterial* Material)
{
// ...
FMaterialShadingModelField ShadingModels = Material->GetShadingModels();
if (ShadingModels.HasOnlyShadingModel(MSM_Unlit))
{
INC_DWORD_STAT_BY(STAT_ShaderCompiling_NumUnlitMaterialShaders, 1);
}
// Mercury Toon Begin
else if (ShadingModels.HasAnyShadingModel({ MSM_DefaultLit, MSM_Subsurface, MSM_PreintegratedSkin, MSM_ClearCoat, MSM_Cloth, MSM_SubsurfaceProfile, MSM_TwoSidedFoliage, MSM_SingleLayerWater, MSM_ThinTranslucent, MSM_MercuryToon }))
// Mercury Toon End
{
INC_DWORD_STAT_BY(STAT_ShaderCompiling_NumLitMaterialShaders, 1);
}
// ...
}
5. 在 ShderMaterial.h 中添加 shading model 定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
struct FShaderMaterialPropertyDefines
{
//DECLARE_TYPE_LAYOUT(FShaderMaterialPropertyDefines, NonVirtual);
//void ModifyEnvironment(FShaderCompilerEnvironment& OutEnvironment) const; //void WriteFrozenVertexFactoryParameters(FMemoryImageWriter& Writer, const TMemoryImagePtr<FShaderMaterialPropertyDefines>& InPropDefines) const;
uint8 MATERIAL_ENABLE_TRANSLUCENCY_FOGGING : 1;
uint8 MATERIALBLENDING_ANY_TRANSLUCENT : 1;
uint8 MATERIAL_USES_SCENE_COLOR_COPY : 1;
uint8 MATERIALBLENDING_MASKED_USING_COVERAGE : 1;
uint8 MATERIAL_COMPUTE_FOG_PER_PIXEL : 1;
uint8 MATERIAL_SHADINGMODEL_UNLIT : 1;
uint8 MATERIAL_SHADINGMODEL_DEFAULT_LIT : 1;
uint8 MATERIAL_SHADINGMODEL_SUBSURFACE : 1;
uint8 MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN : 1;
uint8 MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE : 1;
uint8 MATERIAL_SHADINGMODEL_CLEAR_COAT : 1;
uint8 MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE : 1;
uint8 MATERIAL_SHADINGMODEL_HAIR : 1;
uint8 MATERIAL_SHADINGMODEL_CLOTH : 1;
uint8 MATERIAL_SHADINGMODEL_EYE : 1;
uint8 MATERIAL_SHADINGMODEL_SINGLELAYERWATER : 1;
uint8 SINGLE_LAYER_WATER_SEPARATED_MAIN_LIGHT : 1;
uint8 MATERIAL_SHADINGMODEL_THIN_TRANSLUCENT : 1;
// Mercury Toon Begin
uint8 MATERIAL_SHADINGMODEL_MERCURY_TOON : 1;
// Mercury Toon End
//...
}
6. 在 HLSLMaterialTranslator.cpp 中的 GetMaterialEnvironment 添加 shading model 环境定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void FHLSLMaterialTranslator::GetMaterialEnvironment(EShaderPlatform InPlatform, FShaderCompilerEnvironment& OutEnvironment)
{
if (EnvironmentDefines->bShadingModelsIsLit)
{
if (EnvironmentDefines->HasShadingModel(MSM_DefaultLit))
{
OutEnvironment.SetDefine(TEXT("MATERIAL_SHADINGMODEL_DEFAULT_LIT"), TEXT("1"));
}
// Mercury Toon Begin
if (EnvironmentDefines->HasShadingModel(MSM_MercuryToon))
{
OutEnvironment.SetDefine(TEXT("MATERIAL_SHADINGMODEL_MERCURY_TOON"), TEXT("1"));
}// Mercury Toon End
}
}
7.
This post is licensed under CC BY 4.0 by the author.