From 089f0dab3acdc963a81845a999455e92bf99dd7a Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 5 Feb 2021 11:55:02 +0100 Subject: [PATCH] Refactor material shaders generator to use modular features as extensions --- .../Features/DeferredShading.hlsl | 84 +++++++++++++++++++ .../Features/ForwardShading.hlsl | 1 + .../MaterialTemplates/Features/Lightmap.hlsl | 2 +- .../MaterialTemplates/SurfaceDeferred.shader | 81 +----------------- .../Editor/MaterialTemplates/Terrain.shader | 72 ---------------- .../Materials/MaterialShaderFeatures.cpp | 7 ++ .../Materials/MaterialShaderFeatures.h | 8 ++ .../MaterialGenerator/MaterialGenerator.cpp | 3 + 8 files changed, 108 insertions(+), 150 deletions(-) create mode 100644 Content/Editor/MaterialTemplates/Features/DeferredShading.hlsl diff --git a/Content/Editor/MaterialTemplates/Features/DeferredShading.hlsl b/Content/Editor/MaterialTemplates/Features/DeferredShading.hlsl new file mode 100644 index 000000000..d3a7a2518 --- /dev/null +++ b/Content/Editor/MaterialTemplates/Features/DeferredShading.hlsl @@ -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 +} diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index 085c66291..c21fe37d2 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -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 diff --git a/Content/Editor/MaterialTemplates/Features/Lightmap.hlsl b/Content/Editor/MaterialTemplates/Features/Lightmap.hlsl index 6f6a44d8b..33ef567ca 100644 --- a/Content/Editor/MaterialTemplates/Features/Lightmap.hlsl +++ b/Content/Editor/MaterialTemplates/Features/Lightmap.hlsl @@ -50,4 +50,4 @@ float3 SampleLightmap(Material material, MaterialInput materialInput) } #endif -@5// Lightmap: Shaders \ No newline at end of file +@5// Lightmap: Shaders diff --git a/Content/Editor/MaterialTemplates/SurfaceDeferred.shader b/Content/Editor/MaterialTemplates/SurfaceDeferred.shader index 9ba1ea3de..17f88e179 100644 --- a/Content/Editor/MaterialTemplates/SurfaceDeferred.shader +++ b/Content/Editor/MaterialTemplates/SurfaceDeferred.shader @@ -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 diff --git a/Content/Editor/MaterialTemplates/Terrain.shader b/Content/Editor/MaterialTemplates/Terrain.shader index f1c257b04..ef8afa2a6 100644 --- a/Content/Editor/MaterialTemplates/Terrain.shader +++ b/Content/Editor/MaterialTemplates/Terrain.shader @@ -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 diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp index 3ed31908c..2a6a97ffa 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp @@ -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"); diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h index 1ee46e2d1..3128a688d 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h @@ -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 { diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp index ea342bd53..531efe315 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp @@ -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)