Refactor material shaders generator to use modular features as extensions

This commit is contained in:
Wojtek Figat
2021-02-05 11:55:02 +01:00
parent 01777a2c1b
commit 089f0dab3a
8 changed files with 108 additions and 150 deletions

View File

@@ -0,0 +1,84 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
@0// Deferred Shading: Defines
@1// Deferred Shading: Includes
@2// Deferred Shading: Constants
@3// Deferred Shading: Resources
@4// Deferred Shading: Utilities
@5// Deferred Shading: Shaders
// Pixel Shader function for GBuffer Pass
META_PS(true, FEATURE_LEVEL_ES2)
META_PERMUTATION_1(USE_LIGHTMAP=0)
META_PERMUTATION_1(USE_LIGHTMAP=1)
void PS_GBuffer(
in PixelInput input
,out float4 Light : SV_Target0
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
// GBuffer
,out float4 RT0 : SV_Target1
,out float4 RT1 : SV_Target2
,out float4 RT2 : SV_Target3
#if USE_GBUFFER_CUSTOM_DATA
,out float4 RT3 : SV_Target4
#endif
#endif
)
{
Light = 0;
#if USE_DITHERED_LOD_TRANSITION
// LOD masking
ClipLODTransition(input);
#endif
// Get material parameters
MaterialInput materialInput = GetMaterialInput(input);
Material material = GetMaterialPS(materialInput);
// Masking
#if MATERIAL_MASKED
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif
#if USE_LIGHTMAP
float3 diffuseColor = GetDiffuseColor(material.Color, material.Metalness);
float3 specularColor = GetSpecularColor(material.Color, material.Specular, material.Metalness);
// Sample lightmap
float3 diffuseIndirectLighting = SampleLightmap(material, materialInput);
// Apply static indirect light
Light.rgb = diffuseColor * diffuseIndirectLighting * AOMultiBounce(material.AO, diffuseColor);
#endif
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
// Pack material properties to GBuffer
RT0 = float4(material.Color, material.AO);
RT1 = float4(material.WorldNormal * 0.5 + 0.5, MATERIAL_SHADING_MODEL * (1.0 / 3.0));
RT2 = float4(material.Roughness, material.Metalness, material.Specular, 0);
// Custom data
#if USE_GBUFFER_CUSTOM_DATA
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE
RT3 = float4(material.SubsurfaceColor, material.Opacity);
#elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
RT3 = float4(material.SubsurfaceColor, material.Opacity);
#else
RT3 = float4(0, 0, 0, 0);
#endif
#endif
// Add light emission
#if USE_EMISSIVE
Light.rgb += material.Emissive;
#endif
#else
// Handle blending as faked forward pass (use Light buffer and skip GBuffer modification)
Light = float4(material.Emissive, material.Opacity);
#endif
}

View File

@@ -26,6 +26,7 @@ Texture2DArray DirectionalLightShadowMap : register(t__SRV__);
@4// Forward Shading: Utilities
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
@5// Forward Shading: Shaders
// Pixel Shader function for Forward Pass
META_PS(USE_FORWARD, FEATURE_LEVEL_ES2)
float4 PS_Forward(PixelInput input) : SV_Target0

View File

@@ -50,4 +50,4 @@ float3 SampleLightmap(Material material, MaterialInput materialInput)
}
#endif
@5// Lightmap: Shaders
@5// Lightmap: Shaders

View File

@@ -651,85 +651,8 @@ void ClipLODTransition(PixelInput input)
}
}
#else
void ClipLODTransition(PixelInput input)
{
}
#endif
// Pixel Shader function for GBuffer Pass
META_PS(true, FEATURE_LEVEL_ES2)
META_PERMUTATION_1(USE_LIGHTMAP=0)
META_PERMUTATION_1(USE_LIGHTMAP=1)
void PS_GBuffer(
in PixelInput input
,out float4 Light : SV_Target0
#if MATERIAL_DOMAIN == MATERIAL_DOMAIN_SURFACE
// GBuffer
,out float4 RT0 : SV_Target1
,out float4 RT1 : SV_Target2
,out float4 RT2 : SV_Target3
#if USE_GBUFFER_CUSTOM_DATA
,out float4 RT3 : SV_Target4
#endif
#endif
)
{
Light = 0;
// LOD masking
ClipLODTransition(input);
// Get material parameters
MaterialInput materialInput = GetMaterialInput(input);
Material material = GetMaterialPS(materialInput);
#if MATERIAL_DOMAIN == MATERIAL_DOMAIN_SURFACE
// Masking
#if MATERIAL_MASKED
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif
#if USE_LIGHTMAP
float3 diffuseColor = GetDiffuseColor(material.Color, material.Metalness);
float3 specularColor = GetSpecularColor(material.Color, material.Specular, material.Metalness);
// Sample lightmap
float3 diffuseIndirectLighting = SampleLightmap(material, materialInput);
// Apply static indirect light
Light.rgb = diffuseColor * diffuseIndirectLighting * AOMultiBounce(material.AO, diffuseColor);
#endif
// Pack material properties to GBuffer
RT0 = float4(material.Color, material.AO);
RT1 = float4(material.WorldNormal * 0.5 + 0.5, MATERIAL_SHADING_MODEL * (1.0 / 3.0));
RT2 = float4(material.Roughness, material.Metalness, material.Specular, 0);
// Custom data
#if USE_GBUFFER_CUSTOM_DATA
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE
RT3 = float4(material.SubsurfaceColor, material.Opacity);
#elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
RT3 = float4(material.SubsurfaceColor, material.Opacity);
#else
RT3 = float4(0, 0, 0, 0);
#endif
#endif
#endif
// Add light emission
#if USE_EMISSIVE
Light.rgb += material.Emissive;
#endif
}
// Pixel Shader function for Depth Pass
META_PS(IS_SURFACE, FEATURE_LEVEL_ES2)
void PS_Depth(PixelInput input
@@ -738,8 +661,10 @@ void PS_Depth(PixelInput input
#endif
)
{
#if USE_DITHERED_LOD_TRANSITION
// LOD masking
ClipLODTransition(input);
#endif
#if MATERIAL_MASKED
// Perform per pixel clipping if material requries it
@@ -757,8 +682,10 @@ void PS_Depth(PixelInput input
META_PS(true, FEATURE_LEVEL_ES2)
float4 PS_MotionVectors(PixelInput input) : SV_Target0
{
#if USE_DITHERED_LOD_TRANSITION
// LOD masking
ClipLODTransition(input);
#endif
#if MATERIAL_MASKED
// Perform per pixel clipping if material requries it

View File

@@ -454,78 +454,6 @@ VertexOutput VS(TerrainVertexInput input)
return output;
}
// Pixel Shader function for GBuffer Pass
META_PS(true, FEATURE_LEVEL_ES2)
META_PERMUTATION_1(USE_LIGHTMAP=0)
META_PERMUTATION_1(USE_LIGHTMAP=1)
void PS_GBuffer(
in PixelInput input
,out float4 Light : SV_Target0
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
,out float4 RT0 : SV_Target1
,out float4 RT1 : SV_Target2
,out float4 RT2 : SV_Target3
#if USE_GBUFFER_CUSTOM_DATA
,out float4 RT3 : SV_Target4
#endif
#endif
)
{
Light = 0;
// Get material parameters
MaterialInput materialInput = GetMaterialInput(input);
Material material = GetMaterialPS(materialInput);
// Masking
#if MATERIAL_MASKED
clip(material.Mask - MATERIAL_MASK_THRESHOLD);
#endif
#if USE_LIGHTMAP
float3 diffuseColor = GetDiffuseColor(material.Color, material.Metalness);
float3 specularColor = GetSpecularColor(material.Color, material.Specular, material.Metalness);
// Sample lightmap
float3 diffuseIndirectLighting = SampleLightmap(material, materialInput);
// Apply static indirect light
Light.rgb = diffuseColor * diffuseIndirectLighting * AOMultiBounce(material.AO, diffuseColor);
#endif
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
// Pack material properties to GBuffer
RT0 = float4(material.Color, material.AO);
RT1 = float4(material.WorldNormal * 0.5 + 0.5, MATERIAL_SHADING_MODEL * (1.0 / 3.0));
RT2 = float4(material.Roughness, material.Metalness, material.Specular, 0);
// Custom data
#if USE_GBUFFER_CUSTOM_DATA
#if MATERIAL_SHADING_MODEL == SHADING_MODEL_SUBSURFACE
RT3 = float4(material.SubsurfaceColor, material.Opacity);
#elif MATERIAL_SHADING_MODEL == SHADING_MODEL_FOLIAGE
RT3 = float4(material.SubsurfaceColor, material.Opacity);
#else
RT3 = float4(0, 0, 0, 0);
#endif
#endif
// Add light emission
#if USE_EMISSIVE
Light.rgb += material.Emissive;
#endif
#else
// Handle blending as faked forward pass (use Light buffer and skip GBuffer modification)
Light = float4(material.Emissive, material.Opacity);
#endif
}
// Pixel Shader function for Depth Pass
META_PS(true, FEATURE_LEVEL_ES2)
void PS_Depth(PixelInput input

View File

@@ -162,6 +162,13 @@ void ForwardShadingFeature::Generate(GeneratorData& data)
data.ResourcesCount = SRVs;
}
void DeferredShadingFeature::Generate(GeneratorData& data)
{
data.Template = TEXT("Features/DeferredShading.hlsl");
data.ConstantsSize = 0;
data.ResourcesCount = 0;
}
void TessellationFeature::Generate(GeneratorData& data)
{
data.Template = TEXT("Features/Tessellation.hlsl");

View File

@@ -43,6 +43,14 @@ struct ForwardShadingFeature : MaterialShaderFeature
#endif
};
// Material shader feature that add support for Deferred shading inside the material shader.
struct DeferredShadingFeature : MaterialShaderFeature
{
#if USE_EDITOR
static void Generate(GeneratorData& data);
#endif
};
// Material shader feature that adds geometry hardware tessellation (using Hull and Domain shaders).
struct TessellationFeature : MaterialShaderFeature
{

View File

@@ -186,6 +186,8 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
ADD_FEATURE(TessellationFeature);
if (materialInfo.BlendMode == MaterialBlendMode::Opaque)
ADD_FEATURE(LightmapFeature);
if (materialInfo.BlendMode == MaterialBlendMode::Opaque)
ADD_FEATURE(DeferredShadingFeature);
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == 0)
ADD_FEATURE(DistortionFeature);
if (materialInfo.BlendMode != MaterialBlendMode::Opaque)
@@ -195,6 +197,7 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
if (materialInfo.TessellationMode != TessellationMethod::None)
ADD_FEATURE(TessellationFeature);
ADD_FEATURE(LightmapFeature);
ADD_FEATURE(DeferredShadingFeature);
break;
case MaterialDomain::Particle:
if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == 0)