Post

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.