Skip to content

Instantly share code, notes, and snippets.

@DarcJC
Created April 21, 2023 17:59
Show Gist options
  • Save DarcJC/b01a8eee7052b992693a0c3e843e6951 to your computer and use it in GitHub Desktop.
Save DarcJC/b01a8eee7052b992693a0c3e843e6951 to your computer and use it in GitHub Desktop.
From 3d69159c4ed9cab8402718146be8dde12e537163 Mon Sep 17 00:00:00 2001
From: DarcJC <me@darc.pro>
Date: Sat, 22 Apr 2023 01:58:37 +0800
Subject: [PATCH] feat: add cartoon shading model
---
Engine/Shaders/Private/BasePassCommon.ush | 4 +-
.../Shaders/Private/BasePassPixelShader.usf | 24 ++++++++--
.../ClusteredDeferredShadingPixelShader.usf | 3 ++
.../Shaders/Private/DeferredShadingCommon.ush | 12 ++++-
Engine/Shaders/Private/Definitions.usf | 6 +++
.../ReflectionEnvironmentPixelShader.usf | 8 ++++
Engine/Shaders/Private/ShadingCommon.ush | 11 ++++-
Engine/Shaders/Private/ShadingModels.ush | 48 +++++++++++++++++++
.../Shaders/Private/ShadingModelsMaterial.ush | 9 ++++
.../Private/SkyLightingDiffuseShared.ush | 14 ++++++
.../Engine/Classes/Engine/EngineTypes.h | 3 ++
.../Materials/HLSLMaterialTranslator.cpp | 7 +++
.../Engine/Private/Materials/Material.cpp | 20 ++++++--
.../MaterialAttributeDefinitionMap.cpp | 22 ++++++++-
.../Private/Materials/MaterialHLSLEmitter.cpp | 7 +++
.../ShaderCompiler/ShaderGenerationUtil.cpp | 11 +++++
.../Runtime/Engine/Public/MaterialShared.h | 5 +-
.../Private/ShaderMaterialDerivedHelpers.cpp | 4 +-
.../RenderCore/Public/ShaderMaterial.h | 1 +
19 files changed, 202 insertions(+), 17 deletions(-)
diff --git a/Engine/Shaders/Private/BasePassCommon.ush b/Engine/Shaders/Private/BasePassCommon.ush
index 12e1c2b5b697..3cc79bb3faa6 100644
--- a/Engine/Shaders/Private/BasePassCommon.ush
+++ b/Engine/Shaders/Private/BasePassCommon.ush
@@ -39,7 +39,9 @@
#define USES_GBUFFER (FEATURE_LEVEL >= FEATURE_LEVEL_SM4 && (MATERIALBLENDING_SOLID || MATERIALBLENDING_MASKED) && !FORWARD_SHADING)
// Only some shader models actually need custom data.
-#define WRITES_CUSTOMDATA_TO_GBUFFER (USES_GBUFFER && (MATERIAL_SHADINGMODEL_SUBSURFACE || MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE || MATERIAL_SHADINGMODEL_CLEAR_COAT || MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE || MATERIAL_SHADINGMODEL_HAIR || MATERIAL_SHADINGMODEL_CLOTH || MATERIAL_SHADINGMODEL_EYE))
+// darczeng start
+#define WRITES_CUSTOMDATA_TO_GBUFFER (USES_GBUFFER && (MATERIAL_SHADINGMODEL_SUBSURFACE || MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE || MATERIAL_SHADINGMODEL_CLEAR_COAT || MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE || MATERIAL_SHADINGMODEL_HAIR || MATERIAL_SHADINGMODEL_CLOTH || MATERIAL_SHADINGMODEL_EYE || MATERIAL_SHADINGMODEL_CARTOON))
+// darczeng end
// Based on GetPrecomputedShadowMasks()
// Note: WRITES_PRECSHADOWFACTOR_TO_GBUFFER is currently disabled because we use the precomputed shadow factor GBuffer outside of STATICLIGHTING_TEXTUREMASK to store UseSingleSampleShadowFromStationaryLights
diff --git a/Engine/Shaders/Private/BasePassPixelShader.usf b/Engine/Shaders/Private/BasePassPixelShader.usf
index 8a9925a9ca4a..67c9801d6aa6 100644
--- a/Engine/Shaders/Private/BasePassPixelShader.usf
+++ b/Engine/Shaders/Private/BasePassPixelShader.usf
@@ -876,8 +876,10 @@ void FPixelShaderInOut_MainPS(
// 0..1, SubsurfaceProfileId = int(x * 255)
float SubsurfaceProfile = 0;
#if !STRATA_ENABLED
-#if MATERIAL_SHADINGMODEL_SUBSURFACE || MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE || MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE || MATERIAL_SHADINGMODEL_CLOTH || MATERIAL_SHADINGMODEL_EYE
- if (ShadingModel == SHADINGMODELID_SUBSURFACE || ShadingModel == SHADINGMODELID_PREINTEGRATED_SKIN || ShadingModel == SHADINGMODELID_SUBSURFACE_PROFILE || ShadingModel == SHADINGMODELID_TWOSIDED_FOLIAGE || ShadingModel == SHADINGMODELID_CLOTH || ShadingModel == SHADINGMODELID_EYE)
+// darczeng start
+#if MATERIAL_SHADINGMODEL_SUBSURFACE || MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE || MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE || MATERIAL_SHADINGMODEL_CLOTH || MATERIAL_SHADINGMODEL_EYE || MATERIAL_SHADINGMODEL_CARTOON
+ if (ShadingModel == SHADINGMODELID_SUBSURFACE || ShadingModel == SHADINGMODELID_PREINTEGRATED_SKIN || ShadingModel == SHADINGMODELID_SUBSURFACE_PROFILE || ShadingModel == SHADINGMODELID_TWOSIDED_FOLIAGE || ShadingModel == SHADINGMODELID_CLOTH || ShadingModel == SHADINGMODELID_EYE || ShadingModel == SHADINGMODELID_CARTOON)
+// darczeng end
{
float4 SubsurfaceData = GetMaterialSubsurfaceData(PixelMaterialInputs);
@@ -890,8 +892,10 @@ void FPixelShaderInOut_MainPS(
SubsurfaceColor = SubsurfaceData.rgb * View.DiffuseOverrideParameter.w + View.DiffuseOverrideParameter.xyz;
}
#endif
-#if MATERIAL_SHADINGMODEL_CLOTH
- else if (ShadingModel == SHADINGMODELID_CLOTH)
+// darczeng start
+#if MATERIAL_SHADINGMODEL_CLOTH || MATERIAL_SHADINGMODEL_CARTOON
+ else if (ShadingModel == SHADINGMODELID_CLOTH || ShadingModel == SHADINGMODELID_CARTOON)
+// darczeng end
{
SubsurfaceColor = SubsurfaceData.rgb;
}
@@ -1076,6 +1080,12 @@ void FPixelShaderInOut_MainPS(
// So that the following code can still use DiffuseColor and SpecularColor.
GBuffer.SpecularColor = ComputeF0(Specular, BaseColor, Metallic);
+ // darczeng start
+ if (GBuffer.ShadingModelID == SHADINGMODELID_CARTOON)
+ {
+ GBuffer.SpecularColor = float3(0.0f, 0.0f, 0.0f);
+ }
+ // darczeng end
#if MATERIAL_NORMAL_CURVATURE_TO_ROUGHNESS
const float GeometricAARoughness = GetRoughnessFromNormalCurvature(MaterialParameters);
@@ -1098,6 +1108,12 @@ void FPixelShaderInOut_MainPS(
}
#endif
GBuffer.DiffuseColor = BaseColor - BaseColor * Metallic;
+ // darczeng start
+ if (GBuffer.ShadingModelID == SHADINGMODELID_CARTOON)
+ {
+ GBuffer.DiffuseColor = float3(0.0f, 0.0f, 0.0f);
+ }
+ // darczeng end
#if USE_DEVELOPMENT_SHADERS
{
diff --git a/Engine/Shaders/Private/ClusteredDeferredShadingPixelShader.usf b/Engine/Shaders/Private/ClusteredDeferredShadingPixelShader.usf
index 4ba969eb0c33..5f26ceabca7d 100644
--- a/Engine/Shaders/Private/ClusteredDeferredShadingPixelShader.usf
+++ b/Engine/Shaders/Private/ClusteredDeferredShadingPixelShader.usf
@@ -497,6 +497,9 @@ void ClusteredShadingPixelShader(
GET_LIGHT_GRID_LOCAL_LIGHTING_SINGLE_SM(SHADINGMODELID_CLOTH, PixelShadingModelID, CompositedLighting, ScreenUV, CulledLightGridData, Dither, FirstNonSimpleLightIndex);
GET_LIGHT_GRID_LOCAL_LIGHTING_SINGLE_SM(SHADINGMODELID_EYE, PixelShadingModelID, CompositedLighting, ScreenUV, CulledLightGridData, Dither, FirstNonSimpleLightIndex);
GET_LIGHT_GRID_LOCAL_LIGHTING_SINGLE_SM(SHADINGMODELID_SINGLELAYERWATER, PixelShadingModelID, CompositedLighting, ScreenUV, CulledLightGridData, Dither, FirstNonSimpleLightIndex);
+ // darczeng start
+ GET_LIGHT_GRID_LOCAL_LIGHTING_SINGLE_SM(SHADINGMODELID_CARTOON, PixelShadingModelID, CompositedLighting, ScreenUV, CulledLightGridData, Dither, FirstNonSimpleLightIndex);
+ // darczeng end
// SHADINGMODELID_THIN_TRANSLUCENT - skipping because it can not be opaque
#else // !USE_PASS_PER_SHADING_MODEL
CompositedLighting += GetLightGridLocalLighting(GetScreenSpaceData(ScreenUV), CulledLightGridData, TranslatedWorldPosition, CameraVector, ScreenUV, 0, Dither, FirstNonSimpleLightIndex);
diff --git a/Engine/Shaders/Private/DeferredShadingCommon.ush b/Engine/Shaders/Private/DeferredShadingCommon.ush
index 574a54616662..d40b71c4f0ff 100644
--- a/Engine/Shaders/Private/DeferredShadingCommon.ush
+++ b/Engine/Shaders/Private/DeferredShadingCommon.ush
@@ -300,7 +300,11 @@ bool IsSubsurfaceModel(int ShadingModel)
|| ShadingModel == SHADINGMODELID_SUBSURFACE_PROFILE
|| ShadingModel == SHADINGMODELID_TWOSIDED_FOLIAGE
|| ShadingModel == SHADINGMODELID_HAIR
- || ShadingModel == SHADINGMODELID_EYE;
+ // darczeng start
+ || ShadingModel == SHADINGMODELID_EYE
+ || ShadingModel == SHADINGMODELID_CARTOON
+ ;
+ // darczeng end
}
bool UseSubsurfaceProfile(int ShadingModel)
@@ -317,7 +321,11 @@ bool HasCustomGBufferData(int ShadingModelID)
|| ShadingModelID == SHADINGMODELID_TWOSIDED_FOLIAGE
|| ShadingModelID == SHADINGMODELID_HAIR
|| ShadingModelID == SHADINGMODELID_CLOTH
- || ShadingModelID == SHADINGMODELID_EYE;
+ // darczeng start
+ || ShadingModelID == SHADINGMODELID_EYE
+ || ShadingModelID == SHADINGMODELID_CARTOON
+ ;
+ // darczeng end
}
bool HasAnisotropy(int SelectiveOutputMask)
diff --git a/Engine/Shaders/Private/Definitions.usf b/Engine/Shaders/Private/Definitions.usf
index 3497c111d557..7dbf3a6a8d90 100644
--- a/Engine/Shaders/Private/Definitions.usf
+++ b/Engine/Shaders/Private/Definitions.usf
@@ -116,6 +116,12 @@
#define MATERIAL_SHADINGMODEL_UNLIT 0
#endif
+// darczeng start
+#ifndef MATERIAL_SHADINGMODEL_CARTOON
+#define MATERIAL_SHADINGMODEL_CARTOON 0
+#endif
+// darczeng end
+
#ifndef MATERIAL_SHADINGMODEL_SINGLELAYERWATER
#define MATERIAL_SHADINGMODEL_SINGLELAYERWATER 0
#endif
diff --git a/Engine/Shaders/Private/ReflectionEnvironmentPixelShader.usf b/Engine/Shaders/Private/ReflectionEnvironmentPixelShader.usf
index c1992f9ba7a8..b38539d5ddcb 100644
--- a/Engine/Shaders/Private/ReflectionEnvironmentPixelShader.usf
+++ b/Engine/Shaders/Private/ReflectionEnvironmentPixelShader.usf
@@ -223,6 +223,14 @@ float3 ReflectionEnvironment(FGBufferData GBuffer, float AmbientOcclusion, float
#endif
}
+ // darczeng start
+ BRANCH
+ if (GBuffer.ShadingModelID == SHADINGMODELID_CARTOON)
+ {
+ return float3(0.0f, 0.0f, 0.0f);
+ }
+ // darczeng start
+
// Transform NaNs to black, transform negative colors to black.
return -min(-Color.rgb, 0.0);
}
diff --git a/Engine/Shaders/Private/ShadingCommon.ush b/Engine/Shaders/Private/ShadingCommon.ush
index 7a2b89ed7e09..a6773728dc06 100644
--- a/Engine/Shaders/Private/ShadingCommon.ush
+++ b/Engine/Shaders/Private/ShadingCommon.ush
@@ -30,7 +30,10 @@
#define SHADINGMODELID_SINGLELAYERWATER 10
#define SHADINGMODELID_THIN_TRANSLUCENT 11
#define SHADINGMODELID_STRATA 12 // Temporary while we convert everything to Strata
-#define SHADINGMODELID_NUM 13
+// darczeng start
+#define SHADINGMODELID_CARTOON 13
+#define SHADINGMODELID_NUM 14
+// darczeng end
#define SHADINGMODELID_MASK 0xF // 4 bits reserved for ShadingModelID
// The flags are defined so that 0 value has no effect!
@@ -62,6 +65,9 @@ float3 GetShadingModelColor(uint ShadingModelID)
else if (ShadingModelID == SHADINGMODELID_SINGLELAYERWATER) return float3(0.5f, 0.5f, 1.0f);
else if (ShadingModelID == SHADINGMODELID_THIN_TRANSLUCENT) return float3(1.0f, 0.8f, 0.3f);
else if (ShadingModelID == SHADINGMODELID_STRATA) return float3(1.0f, 1.0f, 0.0f);
+ // darczeng start
+ else if (ShadingModelID == SHADINGMODELID_CARTOON) return float3(0.3f, 0.5f, 0.3f);
+ // darczeng end
else return float3(1.0f, 1.0f, 1.0f); // White
#else
switch(ShadingModelID)
@@ -79,6 +85,9 @@ float3 GetShadingModelColor(uint ShadingModelID)
case SHADINGMODELID_SINGLELAYERWATER: return float3(0.5f, 0.5f, 1.0f);
case SHADINGMODELID_THIN_TRANSLUCENT: return float3(1.0f, 0.8f, 0.3f);
case SHADINGMODELID_STRATA: return float3(1.0f, 1.0f, 0.0f);
+ // darczeng start
+ case SHADINGMODELID_CARTOON: return float3(0.3f, 0.5f, 0.3f);
+ // darczeng end
default: return float3(1.0f, 1.0f, 1.0f); // White
}
#endif
diff --git a/Engine/Shaders/Private/ShadingModels.ush b/Engine/Shaders/Private/ShadingModels.ush
index e2c2261bf1fb..964c8e9a6b1c 100644
--- a/Engine/Shaders/Private/ShadingModels.ush
+++ b/Engine/Shaders/Private/ShadingModels.ush
@@ -958,6 +958,50 @@ FDirectLighting PreintegratedSkinBxDF( FGBufferData GBuffer, half3 N, half3 V, h
return Lighting;
}
+// darczeng start
+FDirectLighting CartoonBxDF( FGBufferData GBuffer, half3 N, half3 V, half3 L, float Falloff, half NoL, FAreaLight AreaLight, FShadowTerms Shadow )
+{
+ BxDFContext Context;
+ FDirectLighting Lighting;
+
+ // Init BxDFContext
+#if SHADING_PATH_MOBILE
+ InitMobile(Context, N, V, L, NoL);
+#else
+ Init(Context, N, V, L);
+#endif
+
+ // Not actual light color, but the distance+angle falloff of the light
+ const float3 LightColor = AreaLight.FalloffColor * Falloff;
+ // Decode GBuffer
+ const float SpecularRange = GBuffer.Metallic;
+ const float SpecularIntensity = GBuffer.Specular;
+ const float ShadowThreshold = GBuffer.Roughness;
+ float InnerLine = GBuffer.CustomData.a;
+ const float3 SSSColor = ExtractSubsurfaceColor(GBuffer);
+ // Bright color and shadow color
+ const float3 BrightColor = GBuffer.BaseColor;
+ const float3 ShadowColor = GBuffer.BaseColor * SSSColor;
+ // Outline Thickness
+ if (InnerLine < 0.8f)
+ {
+ InnerLine *= 0.5f;
+ }
+ const float3 InnerLineColor = float3(InnerLine, InnerLine, InnerLine);
+
+ // Blinn Phong Lighting
+ const float NoH = Context.NoH;
+ // Shadow area
+ const float IsShadow = step(ShadowThreshold, NoL * Shadow.SurfaceShadow);
+ // Lighting
+ Lighting.Diffuse = InnerLineColor * LightColor * Diffuse_Lambert(lerp(ShadowColor, BrightColor, IsShadow));
+ Lighting.Specular = LightColor * BrightColor * IsShadow * InnerLineColor * step(0.2f, SpecularRange * pow(NoH, SpecularIntensity));
+ Lighting.Transmission = 0;
+
+ return Lighting;
+}
+// darczeng end
+
FDirectLighting IntegrateBxDF( FGBufferData GBuffer, half3 N, half3 V, half3 L, float Falloff, half NoL, FAreaLight AreaLight, FShadowTerms Shadow )
{
switch( GBuffer.ShadingModelID )
@@ -982,6 +1026,10 @@ FDirectLighting IntegrateBxDF( FGBufferData GBuffer, half3 N, half3 V, half3 L,
return ClothBxDF( GBuffer, N, V, L, Falloff, NoL, AreaLight, Shadow );
case SHADINGMODELID_EYE:
return EyeBxDF( GBuffer, N, V, L, Falloff, NoL, AreaLight, Shadow );
+ // darczeng start
+ case SHADINGMODELID_CARTOON:
+ return CartoonBxDF( GBuffer, N, V, L, Falloff, NoL, AreaLight, Shadow );
+ // darczeng end
default:
return (FDirectLighting)0;
}
diff --git a/Engine/Shaders/Private/ShadingModelsMaterial.ush b/Engine/Shaders/Private/ShadingModelsMaterial.ush
index 61033ec51ba3..fd7e5063798d 100644
--- a/Engine/Shaders/Private/ShadingModelsMaterial.ush
+++ b/Engine/Shaders/Private/ShadingModelsMaterial.ush
@@ -201,4 +201,13 @@ void SetGBufferForShadingModel(
#endif
}
#endif
+// darczeng start
+#if MATERIAL_SHADINGMODEL_CARTOON
+ else if (ShadingModel == SHADINGMODELID_CARTOON)
+ {
+ GBuffer.CustomData.rgb = EncodeSubsurfaceColor(SubsurfaceColor);
+ GBuffer.CustomData.a = saturate(GetMaterialCustomData0(MaterialParameters));
+ }
+#endif
+// darczeng end
}
\ No newline at end of file
diff --git a/Engine/Shaders/Private/SkyLightingDiffuseShared.ush b/Engine/Shaders/Private/SkyLightingDiffuseShared.ush
index 190261667c16..9b6580cca03c 100644
--- a/Engine/Shaders/Private/SkyLightingDiffuseShared.ush
+++ b/Engine/Shaders/Private/SkyLightingDiffuseShared.ush
@@ -126,6 +126,20 @@ float3 SkyLightDiffuse(FGBufferData GBuffer, float AmbientOcclusion, float2 Buff
DiffuseColor += ClothFuzz * GBuffer.CustomData.a;
}
+ // darczeng start
+ BRANCH
+ if (GBuffer.ShadingModelID == SHADINGMODELID_CARTOON)
+ {
+ float InnerLine = GBuffer.CustomData.a;
+ if (InnerLine < 0.8f)
+ {
+ InnerLine *= 0.5f;
+ }
+ const float3 InnerLineColor = float3(InnerLine, InnerLine, InnerLine);
+ Lighting = InnerLineColor * GBuffer.BaseColor * View.SkyLightColor.rgb * 0.05f;
+ }
+ // darczeng end
+
// Compute the preconvolved incoming lighting with the bent normal direction
float3 DiffuseLookup = GetSkySHDiffuse(SkyVisData.SkyDiffuseLookUpNormal) * View.SkyLightColor.rgb;
diff --git a/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h b/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h
index 6f75e5e646e7..a9e44d48a187 100644
--- a/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h
+++ b/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h
@@ -615,6 +615,9 @@ enum EMaterialShadingModel : int
MSM_SingleLayerWater UMETA(DisplayName="SingleLayerWater"),
MSM_ThinTranslucent UMETA(DisplayName="Thin Translucent"),
MSM_Strata UMETA(DisplayName="Substrate", Hidden),
+ // darczeng start
+ MSM_Cartoon UMETA(DisplayName="Cartoon"),
+ // darczeng end
/** Number of unique shading models. */
MSM_NUM UMETA(Hidden),
/** Shading model will be determined by the Material Expression Graph,
diff --git a/Engine/Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp b/Engine/Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp
index 3387796ea1c4..3c20d2fc3321 100644
--- a/Engine/Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp
+++ b/Engine/Source/Runtime/Engine/Private/Materials/HLSLMaterialTranslator.cpp
@@ -1930,6 +1930,13 @@ void FHLSLMaterialTranslator::GetMaterialEnvironment(EShaderPlatform InPlatform,
bMaterialRequestsDualSourceBlending = true;
}
+ // darczeng start
+ if (ShadingModels.HasShadingModel(MSM_Cartoon))
+ {
+ OutEnvironment.SetDefine(TEXT("MATERIAL_SHADINGMODEL_CARTOON"), TEXT("1"));
+ NumSetMaterials++;
+ }
+ // darczeng end
if (ShadingModels.HasShadingModel(MSM_SingleLayerWater) && FDataDrivenShaderPlatformInfo::GetRequiresDisableForwardLocalLights(Platform))
{
diff --git a/Engine/Source/Runtime/Engine/Private/Materials/Material.cpp b/Engine/Source/Runtime/Engine/Private/Materials/Material.cpp
index 13eafa53e203..fdaf130c4355 100644
--- a/Engine/Source/Runtime/Engine/Private/Materials/Material.cpp
+++ b/Engine/Source/Runtime/Engine/Private/Materials/Material.cpp
@@ -6725,7 +6725,9 @@ static bool IsPropertyActive_Internal(EMaterialProperty InProperty,
Active = ShadingModels.IsLit() && (!bIsTranslucentBlendMode || !bIsVolumetricTranslucencyLightingMode);
break;
case MP_Anisotropy:
- Active = ShadingModels.HasAnyShadingModel({ MSM_DefaultLit, MSM_ClearCoat }) && (!bIsTranslucentBlendMode || !bIsVolumetricTranslucencyLightingMode);
+ // darczeng start
+ Active = ShadingModels.HasAnyShadingModel({ MSM_DefaultLit, MSM_ClearCoat, MSM_Cartoon }) && (!bIsTranslucentBlendMode || !bIsVolumetricTranslucencyLightingMode);
+ // darczeng end
break;
case MP_Metallic:
// Subsurface models store opacity in place of Metallic in the GBuffer
@@ -6735,16 +6737,24 @@ static bool IsPropertyActive_Internal(EMaterialProperty InProperty,
Active = (ShadingModels.IsLit() && (!bIsTranslucentBlendMode || !bIsNonDirectionalTranslucencyLightingMode)) || bUsesDistortion;
break;
case MP_Tangent:
- Active = ShadingModels.HasAnyShadingModel({ MSM_DefaultLit, MSM_ClearCoat }) && (!bIsTranslucentBlendMode || !bIsVolumetricTranslucencyLightingMode);
+ // darczeng start
+ Active = ShadingModels.HasAnyShadingModel({ MSM_DefaultLit, MSM_ClearCoat, MSM_Cartoon }) && (!bIsTranslucentBlendMode || !bIsVolumetricTranslucencyLightingMode);
+ // darczeng end
break;
case MP_SubsurfaceColor:
- Active = ShadingModels.HasAnyShadingModel({ MSM_Subsurface, MSM_PreintegratedSkin, MSM_TwoSidedFoliage, MSM_Cloth });
+ // darczeng start
+ Active = ShadingModels.HasAnyShadingModel({ MSM_Subsurface, MSM_PreintegratedSkin, MSM_TwoSidedFoliage, MSM_Cloth, MSM_Cartoon });
+ // darczeng end
break;
case MP_CustomData0:
- Active = ShadingModels.HasAnyShadingModel({ MSM_ClearCoat, MSM_Hair, MSM_Cloth, MSM_Eye, MSM_SubsurfaceProfile });
+ // darczeng start
+ Active = ShadingModels.HasAnyShadingModel({ MSM_ClearCoat, MSM_Hair, MSM_Cloth, MSM_Eye, MSM_SubsurfaceProfile, MSM_Cartoon });
+ // darczeng end
break;
case MP_CustomData1:
- Active = ShadingModels.HasAnyShadingModel({ MSM_ClearCoat, MSM_Eye });
+ // darczeng start
+ Active = ShadingModels.HasAnyShadingModel({ MSM_ClearCoat, MSM_Eye, MSM_Cartoon });
+ // darczeng end
break;
case MP_EmissiveColor:
// Emissive is always active, even for light functions and post process materials,
diff --git a/Engine/Source/Runtime/Engine/Private/Materials/MaterialAttributeDefinitionMap.cpp b/Engine/Source/Runtime/Engine/Private/Materials/MaterialAttributeDefinitionMap.cpp
index 8e5ecddc24b1..2088ff7b12cd 100644
--- a/Engine/Source/Runtime/Engine/Private/Materials/MaterialAttributeDefinitionMap.cpp
+++ b/Engine/Source/Runtime/Engine/Private/Materials/MaterialAttributeDefinitionMap.cpp
@@ -369,11 +369,20 @@ FText FMaterialAttributeDefinitionMap::GetAttributeOverrideForMaterial(const FGu
case MP_Metallic:
CustomPinNames.Add({ MSM_Hair, "Scatter" });
CustomPinNames.Add({ MSM_Eye, "Curvature" });
+ // darczeng start
+ CustomPinNames.Add({ MSM_Cartoon, "Specular Range" });
+ // darczeng end
return FText::FromString(GetPinNameFromShadingModelField(Material->GetShadingModels(), CustomPinNames, "Metallic"));
case MP_Specular:
- return LOCTEXT("Specular", "Specular");
+ // darczeng start
+ CustomPinNames.Add({ MSM_Cartoon, "Specular Intensity" });
+ return FText::FromString(GetPinNameFromShadingModelField(Material->GetShadingModels(), CustomPinNames, "Specular"));
+ // darczeng end
case MP_Roughness:
- return LOCTEXT("Roughness", "Roughness");
+ // darczeng start
+ CustomPinNames.Add({ MSM_Cartoon, "Shadow Threshold" });
+ return FText::FromString(GetPinNameFromShadingModelField(Material->GetShadingModels(), CustomPinNames, "Roughness"));
+ // darczeng end
case MP_Anisotropy:
return LOCTEXT("Anisotropy", "Anisotropy");
case MP_Normal:
@@ -393,6 +402,9 @@ FText FMaterialAttributeDefinitionMap::GetAttributeOverrideForMaterial(const FGu
return LOCTEXT("Extinction", "Extinction");
}
CustomPinNames.Add({ MSM_Cloth, "Fuzz Color" });
+ // darczeng start
+ CustomPinNames.Add({ MSM_Cartoon, "SSS Color" });
+ // darczeng end
return FText::FromString(GetPinNameFromShadingModelField(Material->GetShadingModels(), CustomPinNames, "Subsurface Color"));
case MP_CustomData0:
CustomPinNames.Add({ MSM_ClearCoat, "Clear Coat" });
@@ -400,10 +412,16 @@ FText FMaterialAttributeDefinitionMap::GetAttributeOverrideForMaterial(const FGu
CustomPinNames.Add({ MSM_Cloth, "Cloth" });
CustomPinNames.Add({ MSM_Eye, "Iris Mask" });
CustomPinNames.Add({ MSM_SubsurfaceProfile, "Curvature" });
+ // darczeng start
+ CustomPinNames.Add( { MSM_Cartoon, "Inner Line" });
+ // darczeng end
return FText::FromString(GetPinNameFromShadingModelField(Material->GetShadingModels(), CustomPinNames, "Custom Data 0"));
case MP_CustomData1:
CustomPinNames.Add({ MSM_ClearCoat, "Clear Coat Roughness" });
CustomPinNames.Add({ MSM_Eye, "Iris Distance" });
+ // darczeng start
+ CustomPinNames.Add( { MSM_Cartoon, "Other" });
+ // darczeng end
return FText::FromString(GetPinNameFromShadingModelField(Material->GetShadingModels(), CustomPinNames, "Custom Data 1"));
case MP_AmbientOcclusion:
return LOCTEXT("AmbientOcclusion", "Ambient Occlusion");
diff --git a/Engine/Source/Runtime/Engine/Private/Materials/MaterialHLSLEmitter.cpp b/Engine/Source/Runtime/Engine/Private/Materials/MaterialHLSLEmitter.cpp
index a5a1ca6a93e5..969d13dd87fb 100644
--- a/Engine/Source/Runtime/Engine/Private/Materials/MaterialHLSLEmitter.cpp
+++ b/Engine/Source/Runtime/Engine/Private/Materials/MaterialHLSLEmitter.cpp
@@ -610,6 +610,13 @@ static void GetMaterialEnvironment(EShaderPlatform InPlatform,
bMaterialRequestsDualSourceBlending = true;
}
+ // darczeng start
+ if (ShadingModels.HasShadingModel(MSM_Cartoon))
+ {
+ OutEnvironment.SetDefine(TEXT("MATERIAL_SHADINGMODEL_CARTOON"), TEXT("1"));
+ NumSetMaterials++;
+ }
+ // darczeng end
if (ShadingModels.HasShadingModel(MSM_SingleLayerWater) && FDataDrivenShaderPlatformInfo::GetRequiresDisableForwardLocalLights(InPlatform))
{
diff --git a/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderGenerationUtil.cpp b/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderGenerationUtil.cpp
index d3a56eb8847d..54e125f0f1f4 100644
--- a/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderGenerationUtil.cpp
+++ b/Engine/Source/Runtime/Engine/Private/ShaderCompiler/ShaderGenerationUtil.cpp
@@ -146,6 +146,9 @@ void FShaderCompileUtilities::ApplyFetchEnvironment(FShaderMaterialPropertyDefin
FETCH_COMPILE_BOOL(MATERIAL_SHADINGMODEL_EYE);
FETCH_COMPILE_BOOL(MATERIAL_SHADINGMODEL_SINGLELAYERWATER);
FETCH_COMPILE_BOOL(MATERIAL_SHADINGMODEL_THIN_TRANSLUCENT);
+ // darczeng start
+ FETCH_COMPILE_BOOL(MATERIAL_SHADINGMODEL_CARTOON);
+ // darczeng end
FETCH_COMPILE_BOOL(SINGLE_LAYER_WATER_SEPARATED_MAIN_LIGHT);
@@ -1794,6 +1797,14 @@ static void DetermineUsedMaterialSlots(
{
}
+ // darczeng start
+ if (Mat.MATERIAL_SHADINGMODEL_CARTOON)
+ {
+ SetStandardGBufferSlots(Slots, bWriteEmissive, bHasTangent, bHasVelocity, bHasStaticLighting, bIsStrataMaterial);
+ Slots[GBS_CustomData] = bUseCustomData;
+ }
+ // darczeng end
+
}
void FShaderCompileUtilities::ApplyDerivedDefines(FShaderCompilerEnvironment& OutEnvironment, FShaderCompilerEnvironment * SharedEnvironment, const EShaderPlatform Platform)
diff --git a/Engine/Source/Runtime/Engine/Public/MaterialShared.h b/Engine/Source/Runtime/Engine/Public/MaterialShared.h
index c32436448cb1..270cae245540 100644
--- a/Engine/Source/Runtime/Engine/Public/MaterialShared.h
+++ b/Engine/Source/Runtime/Engine/Public/MaterialShared.h
@@ -127,7 +127,10 @@ inline bool IsSubsurfaceShadingModel(FMaterialShadingModelField ShadingModel)
{
return ShadingModel.HasShadingModel(MSM_Subsurface) || ShadingModel.HasShadingModel(MSM_PreintegratedSkin) ||
ShadingModel.HasShadingModel(MSM_SubsurfaceProfile) || ShadingModel.HasShadingModel(MSM_TwoSidedFoliage) ||
- ShadingModel.HasShadingModel(MSM_Cloth) || ShadingModel.HasShadingModel(MSM_Eye);
+ // darczeng start
+ ShadingModel.HasShadingModel(MSM_Cloth) || ShadingModel.HasShadingModel(MSM_Eye) ||
+ ShadingModel.HasShadingModel(MSM_Cartoon);
+ // darczeng end
}
inline bool UseSubsurfaceProfile(FMaterialShadingModelField ShadingModel)
diff --git a/Engine/Source/Runtime/RenderCore/Private/ShaderMaterialDerivedHelpers.cpp b/Engine/Source/Runtime/RenderCore/Private/ShaderMaterialDerivedHelpers.cpp
index 3fde28e0651c..a82bd1848ea9 100644
--- a/Engine/Source/Runtime/RenderCore/Private/ShaderMaterialDerivedHelpers.cpp
+++ b/Engine/Source/Runtime/RenderCore/Private/ShaderMaterialDerivedHelpers.cpp
@@ -50,7 +50,9 @@ FShaderMaterialDerivedDefines RENDERCORE_API CalculateDerivedMaterialParameters(
Dst.USES_GBUFFER = (FEATURE_LEVEL >= ERHIFeatureLevel::SM4_REMOVED && (Mat.MATERIALBLENDING_SOLID || Mat.MATERIALBLENDING_MASKED) && !SrcGlobal.FORWARD_SHADING);
// Only some shader models actually need custom data.
- Dst.WRITES_CUSTOMDATA_TO_GBUFFER = (Dst.USES_GBUFFER && (Mat.MATERIAL_SHADINGMODEL_SUBSURFACE || Mat.MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || Mat.MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE || Mat.MATERIAL_SHADINGMODEL_CLEAR_COAT || Mat.MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE || Mat.MATERIAL_SHADINGMODEL_HAIR || Mat.MATERIAL_SHADINGMODEL_CLOTH || Mat.MATERIAL_SHADINGMODEL_EYE));
+ // darczeng start
+ Dst.WRITES_CUSTOMDATA_TO_GBUFFER = (Dst.USES_GBUFFER && (Mat.MATERIAL_SHADINGMODEL_SUBSURFACE || Mat.MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || Mat.MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE || Mat.MATERIAL_SHADINGMODEL_CLEAR_COAT || Mat.MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE || Mat.MATERIAL_SHADINGMODEL_HAIR || Mat.MATERIAL_SHADINGMODEL_CLOTH || Mat.MATERIAL_SHADINGMODEL_EYE || Mat.MATERIAL_SHADINGMODEL_CARTOON));
+ // darczeng end
// Based on GetPrecomputedShadowMasks()
// Note: WRITES_PRECSHADOWFACTOR_TO_GBUFFER is currently disabled because we use the precomputed shadow factor GBuffer outside of STATICLIGHTING_TEXTUREMASK to store UseSingleSampleShadowFromStationaryLights
diff --git a/Engine/Source/Runtime/RenderCore/Public/ShaderMaterial.h b/Engine/Source/Runtime/RenderCore/Public/ShaderMaterial.h
index f83f6809ef84..c09d426cd3e5 100644
--- a/Engine/Source/Runtime/RenderCore/Public/ShaderMaterial.h
+++ b/Engine/Source/Runtime/RenderCore/Public/ShaderMaterial.h
@@ -103,6 +103,7 @@ struct FShaderMaterialPropertyDefines
uint8 MATERIAL_SHADINGMODEL_SINGLELAYERWATER : 1;
uint8 SINGLE_LAYER_WATER_SEPARATED_MAIN_LIGHT : 1;
uint8 MATERIAL_SHADINGMODEL_THIN_TRANSLUCENT : 1;
+ uint8 MATERIAL_SHADINGMODEL_CARTOON : 1;
uint8 TRANSLUCENCY_LIGHTING_VOLUMETRIC_NONDIRECTIONAL : 1;
uint8 TRANSLUCENCY_LIGHTING_VOLUMETRIC_DIRECTIONAL : 1;
--
2.36.1.windows.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment