From a219a3d2eb15c3a697fbff3d4f7ec043e252ba95 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 29 Jan 2023 22:09:51 +0100 Subject: [PATCH] Add **Depth Offset to materials** --- .../Features/DeferredShading.hlsl | 10 +++++++++- .../Features/ForwardShading.hlsl | 17 +++++++++++++---- Content/Editor/MaterialTemplates/Surface.shader | 13 +++++++++++-- Source/Editor/Surface/Archetypes/Material.cs | 10 +++++++++- Source/Engine/Content/Assets/Material.cpp | 4 ++++ Source/Engine/Graphics/Materials/MaterialInfo.h | 5 +++++ .../Engine/Graphics/Materials/MaterialShader.h | 2 +- .../MaterialGenerator.Layer.cpp | 2 ++ .../MaterialGenerator.Layers.cpp | 6 ++++++ .../MaterialGenerator/MaterialGenerator.cpp | 1 + .../Tools/MaterialGenerator/MaterialGenerator.h | 6 +++++- .../Tools/MaterialGenerator/MaterialLayer.cpp | 7 +++++-- Source/Shaders/MaterialCommon.hlsl | 3 ++- 13 files changed, 73 insertions(+), 13 deletions(-) diff --git a/Content/Editor/MaterialTemplates/Features/DeferredShading.hlsl b/Content/Editor/MaterialTemplates/Features/DeferredShading.hlsl index 556cc99a1..64cecd4f8 100644 --- a/Content/Editor/MaterialTemplates/Features/DeferredShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/DeferredShading.hlsl @@ -22,6 +22,9 @@ void PS_GBuffer( #if USE_GBUFFER_CUSTOM_DATA ,out float4 RT3 : SV_Target4 #endif +#endif +#if USE_DEPTH_OFFSET + ,out float Depth : SV_Depth #endif ) { @@ -36,11 +39,16 @@ void PS_GBuffer( MaterialInput materialInput = GetMaterialInput(input); Material material = GetMaterialPS(materialInput); + // Depth offset +#if USE_DEPTH_OFFSET + Depth = (materialInput.SvPosition.z * materialInput.SvPosition.w) / (materialInput.SvPosition.w + material.DepthOffset); +#endif + // 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); diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index d395a8bd1..68278f949 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -33,9 +33,15 @@ DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow); // Pixel Shader function for Forward Pass META_PS(USE_FORWARD, FEATURE_LEVEL_ES2) -float4 PS_Forward(PixelInput input) : SV_Target0 +void PS_Forward( + in PixelInput input + ,out float4 output : SV_Target0 +#if USE_DEPTH_OFFSET + ,out float Depth : SV_Depth +#endif + ) { - float4 output = 0; + output = 0; #if USE_DITHERED_LOD_TRANSITION // LOD masking @@ -45,6 +51,11 @@ float4 PS_Forward(PixelInput input) : SV_Target0 // Get material parameters MaterialInput materialInput = GetMaterialInput(input); Material material = GetMaterialPS(materialInput); + + // Depth offset +#if USE_DEPTH_OFFSET + Depth = (materialInput.SvPosition.z * materialInput.SvPosition.w) / (materialInput.SvPosition.w + material.DepthOffset); +#endif // Masking #if MATERIAL_MASKED @@ -148,6 +159,4 @@ float4 PS_Forward(PixelInput input) : SV_Target0 #endif #endif - - return output; } diff --git a/Content/Editor/MaterialTemplates/Surface.shader b/Content/Editor/MaterialTemplates/Surface.shader index 0e7c948a1..3e93ddbb6 100644 --- a/Content/Editor/MaterialTemplates/Surface.shader +++ b/Content/Editor/MaterialTemplates/Surface.shader @@ -587,14 +587,18 @@ void ClipLODTransition(PixelInput input) // Pixel Shader function for Depth Pass META_PS(true, FEATURE_LEVEL_ES2) -void PS_Depth(PixelInput input) +void PS_Depth(PixelInput input +#if USE_DEPTH_OFFSET + ,out float Depth : SV_Depth +#endif + ) { #if USE_DITHERED_LOD_TRANSITION // LOD masking ClipLODTransition(input); #endif -#if MATERIAL_MASKED || MATERIAL_BLEND != MATERIAL_BLEND_OPAQUE +#if MATERIAL_MASKED || MATERIAL_BLEND != MATERIAL_BLEND_OPAQUE || USE_DEPTH_OFFSET // Get material parameters MaterialInput materialInput = GetMaterialInput(input); Material material = GetMaterialPS(materialInput); @@ -606,6 +610,11 @@ void PS_Depth(PixelInput input) #if MATERIAL_BLEND != MATERIAL_BLEND_OPAQUE clip(material.Opacity - MATERIAL_OPACITY_THRESHOLD); #endif + + // Depth offset +#if USE_DEPTH_OFFSET + Depth = (materialInput.SvPosition.z * materialInput.SvPosition.w) / (materialInput.SvPosition.w + material.DepthOffset); +#endif #endif } diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index 1a797c67d..5182dba50 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -40,6 +40,7 @@ namespace FlaxEditor.Surface.Archetypes TessellationMultiplier = 12, WorldDisplacement = 13, SubsurfaceColor = 14, + DepthOffset = 15, }; /// @@ -85,6 +86,7 @@ namespace FlaxEditor.Surface.Archetypes GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = false; GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = false; GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = false; + GetBox(MaterialNodeBoxes.DepthOffset).Enabled = false; return; } @@ -116,6 +118,7 @@ namespace FlaxEditor.Surface.Archetypes GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = withTess; GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = withTess; GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = info.ShadingModel == MaterialShadingModel.Subsurface || info.ShadingModel == MaterialShadingModel.Foliage; + GetBox(MaterialNodeBoxes.DepthOffset).Enabled = true; break; } case MaterialDomain.PostProcess: @@ -134,6 +137,7 @@ namespace FlaxEditor.Surface.Archetypes GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = false; GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = false; GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = false; + GetBox(MaterialNodeBoxes.DepthOffset).Enabled = false; break; } case MaterialDomain.Decal: @@ -154,6 +158,7 @@ namespace FlaxEditor.Surface.Archetypes GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = false; GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = false; GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = false; + GetBox(MaterialNodeBoxes.DepthOffset).Enabled = false; break; } case MaterialDomain.GUI: @@ -172,6 +177,7 @@ namespace FlaxEditor.Surface.Archetypes GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = false; GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = false; GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = false; + GetBox(MaterialNodeBoxes.DepthOffset).Enabled = false; break; } case MaterialDomain.VolumeParticle: @@ -190,6 +196,7 @@ namespace FlaxEditor.Surface.Archetypes GetBox(MaterialNodeBoxes.TessellationMultiplier).Enabled = false; GetBox(MaterialNodeBoxes.WorldDisplacement).Enabled = false; GetBox(MaterialNodeBoxes.SubsurfaceColor).Enabled = false; + GetBox(MaterialNodeBoxes.DepthOffset).Enabled = false; break; } default: throw new ArgumentOutOfRangeException(); @@ -281,7 +288,7 @@ namespace FlaxEditor.Surface.Archetypes Title = "Material", Description = "Main material node", Flags = NodeFlags.MaterialGraph | NodeFlags.NoRemove | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste | NodeFlags.NoCloseButton, - Size = new Float2(150, 300), + Size = new Float2(150, 320), Elements = new[] { NodeElementArchetype.Factory.Input(0, "", true, typeof(void), 0), @@ -299,6 +306,7 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.Input(12, "Tessellation Multiplier", true, typeof(float), 12), NodeElementArchetype.Factory.Input(13, "World Displacement", true, typeof(Float3), 13), NodeElementArchetype.Factory.Input(14, "Subsurface Color", true, typeof(Float3), 14), + NodeElementArchetype.Factory.Input(15, "Depth Offset", true, typeof(float), 15), } }, new NodeArchetype diff --git a/Source/Engine/Content/Assets/Material.cpp b/Source/Engine/Content/Assets/Material.cpp index 76ed34b80..fb2313ff7 100644 --- a/Source/Engine/Content/Assets/Material.cpp +++ b/Source/Engine/Content/Assets/Material.cpp @@ -426,6 +426,9 @@ void Material::InitCompilationOptions(ShaderCompilationOptions& options) info.BlendMode != MaterialBlendMode::Opaque && EnumHasAnyFlags(info.UsageFlags, MaterialUsageFlags::UseRefraction) && (info.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == MaterialFeaturesFlags::None; + const bool useDepthOffset = + (info.Domain == MaterialDomain::Surface) && + EnumHasAnyFlags(info.UsageFlags, MaterialUsageFlags::UseDepthOffset); // @formatter:off static const char* Numbers[] = @@ -496,6 +499,7 @@ void Material::InitCompilationOptions(ShaderCompilationOptions& options) options.Macros.Add({ "USE_FORWARD", Numbers[useForward ? 1 : 0] }); options.Macros.Add({ "USE_DEFERRED", Numbers[isSurfaceOrTerrainOrDeformable && info.BlendMode == MaterialBlendMode::Opaque ? 1 : 0] }); options.Macros.Add({ "USE_DISTORTION", Numbers[useDistortion ? 1 : 0] }); + options.Macros.Add({ "USE_DEPTH_OFFSET", Numbers[useDepthOffset ? 1 : 0] }); #endif } diff --git a/Source/Engine/Graphics/Materials/MaterialInfo.h b/Source/Engine/Graphics/Materials/MaterialInfo.h index 86fab4548..11eb8c14f 100644 --- a/Source/Engine/Graphics/Materials/MaterialInfo.h +++ b/Source/Engine/Graphics/Materials/MaterialInfo.h @@ -330,6 +330,11 @@ API_ENUM(Attributes="Flags") enum class MaterialUsageFlags : uint32 /// The flag used to indicate that material uses refraction feature. /// UseRefraction = 1 << 6, + + /// + /// The flag used to indicate that material uses per-pixel depth offset feature. + /// + UseDepthOffset = 1 << 7, }; DECLARE_ENUM_OPERATORS(MaterialUsageFlags); diff --git a/Source/Engine/Graphics/Materials/MaterialShader.h b/Source/Engine/Graphics/Materials/MaterialShader.h index 007afee67..48a9abe5e 100644 --- a/Source/Engine/Graphics/Materials/MaterialShader.h +++ b/Source/Engine/Graphics/Materials/MaterialShader.h @@ -10,7 +10,7 @@ /// /// Current materials shader version. /// -#define MATERIAL_GRAPH_VERSION 159 +#define MATERIAL_GRAPH_VERSION 160 class Material; class GPUShader; diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layer.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layer.cpp index b7af16cb2..993a61469 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layer.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layer.cpp @@ -27,10 +27,12 @@ MaterialGenerator::MaterialGraphBoxesMapping MaterialGenerator::MaterialGraphBox { 12, TEXT("TessellationMultiplier"), MaterialTreeType::VertexShader, MaterialValue(VariantType::Float, TEXT("4.0f")) }, { 13, TEXT("WorldDisplacement"), MaterialTreeType::DomainShader, MaterialValue::InitForZero(VariantType::Float3) }, { 14, TEXT("SubsurfaceColor"), MaterialTreeType::PixelShader, MaterialValue::InitForZero(VariantType::Float3) }, + { 15, TEXT("DepthOffset"), MaterialTreeType::PixelShader, MaterialValue::InitForZero(VariantType::Float) }, }; const MaterialGenerator::MaterialGraphBoxesMapping& MaterialGenerator::GetMaterialRootNodeBox(MaterialGraphBoxes box) { + static_assert(ARRAY_COUNT(MaterialGenerator::MaterialGraphBoxesMappings) == 16, "Invalid amount of boxes added for root node. Please update the code above"); return MaterialGraphBoxesMappings[static_cast(box)]; } diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layers.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layers.cpp index 63718b329..7007bf7d9 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layers.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Layers.cpp @@ -103,6 +103,7 @@ void MaterialGenerator::ProcessGroupLayers(Box* box, Node* node, Value& value) EAT_BOX(AmbientOcclusion); EAT_BOX(Opacity); EAT_BOX(Refraction); + EAT_BOX(DepthOffset); EAT_BOX(Mask); EAT_BOX(Emissive); EAT_BOX(SubsurfaceColor); @@ -204,6 +205,7 @@ void MaterialGenerator::ProcessGroupLayers(Box* box, Node* node, Value& value) EAT_BOX(AmbientOcclusion); EAT_BOX(Opacity); EAT_BOX(Refraction); + EAT_BOX(DepthOffset); EAT_BOX(Mask); EAT_BOX(Emissive); EAT_BOX(SubsurfaceColor); @@ -246,12 +248,15 @@ void MaterialGenerator::ProcessGroupLayers(Box* box, Node* node, Value& value) EAT_BOX(AmbientOcclusion); EAT_BOX(Opacity); EAT_BOX(Refraction); + EAT_BOX(DepthOffset); EAT_BOX(Mask); EAT_BOX(Emissive); CHECK_MATERIAL_FEATURE(Emissive, UseEmissive); CHECK_MATERIAL_FEATURE(Normal, UseNormal); CHECK_MATERIAL_FEATURE(Mask, UseMask); + CHECK_MATERIAL_FEATURE(Refraction, UseRefraction); + CHECK_MATERIAL_FEATURE(DepthOffset, UseDepthOffset); break; } @@ -331,6 +336,7 @@ void MaterialGenerator::ProcessGroupLayers(Box* box, Node* node, Value& value) CHECK_MATERIAL_FEATURE(Normal, UseNormal); CHECK_MATERIAL_FEATURE(Mask, UseMask); CHECK_MATERIAL_FEATURE(Refraction, UseRefraction); + CHECK_MATERIAL_FEATURE(DepthOffset, UseDepthOffset); break; } diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp index b1aab0049..20722e494 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp @@ -256,6 +256,7 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo eatMaterialGraphBox(baseLayer, MaterialGraphBoxes::Roughness); eatMaterialGraphBox(baseLayer, MaterialGraphBoxes::Opacity); eatMaterialGraphBox(baseLayer, MaterialGraphBoxes::Refraction); + eatMaterialGraphBox(baseLayer, MaterialGraphBoxes::DepthOffset); eatMaterialGraphBox(baseLayer, MaterialGraphBoxes::SubsurfaceColor); eatMaterialGraphBox(baseLayer, MaterialGraphBoxes::Mask); } diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h index 92f238508..d0823d359 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.h @@ -6,7 +6,6 @@ #include "Engine/Graphics/Materials/MaterialInfo.h" #include "Engine/Graphics/Materials/MaterialParams.h" -#include "Engine/Content/AssetsContainer.h" #include "MaterialLayer.h" #include "Types.h" @@ -90,6 +89,11 @@ enum class MaterialGraphBoxes /// SubsurfaceColor = 14, + /// + /// The custom depth offset applied per-pixel. + /// + DepthOffset = 15, + /// /// The amount of input boxes. /// diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialLayer.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialLayer.cpp index 33b3dfed3..8de2d6edb 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialLayer.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialLayer.cpp @@ -129,6 +129,7 @@ void MaterialLayer::UpdateFeaturesFlags() CHECK_BOX_AS_FEATURE(PositionOffset, UsePositionOffset); CHECK_BOX_AS_FEATURE(WorldDisplacement, UseDisplacement); CHECK_BOX_AS_FEATURE(Refraction, UseRefraction); + CHECK_BOX_AS_FEATURE(DepthOffset, UseDepthOffset); #undef CHECK_BOX_AS_FEATURE } @@ -179,7 +180,8 @@ MaterialLayer* MaterialLayer::Load(const Guid& id, ReadStream* graphData, const ADD_BOX(TessellationMultiplier, Float); ADD_BOX(WorldDisplacement, Float3); ADD_BOX(SubsurfaceColor, Float3); - static_assert(static_cast(MaterialGraphBoxes::MAX) == 15, "Invalid amount of boxes added for root node. Please update the code above"); + ADD_BOX(DepthOffset, Float); + static_assert(static_cast(MaterialGraphBoxes::MAX) == 16, "Invalid amount of boxes added for root node. Please update the code above"); ASSERT(layer->Root->Boxes.Count() == static_cast(MaterialGraphBoxes::MAX)); #if BUILD_DEBUG // Test for valid pointers after node upgrade @@ -225,11 +227,12 @@ void MaterialLayer::createRootNode() INIT_BOX(Normal, Float3); INIT_BOX(Opacity, Float); INIT_BOX(Refraction, Float); + INIT_BOX(DepthOffset, Float); INIT_BOX(PositionOffset, Float3); INIT_BOX(TessellationMultiplier, Float); INIT_BOX(WorldDisplacement, Float3); INIT_BOX(SubsurfaceColor, Float3); - static_assert(static_cast(MaterialGraphBoxes::MAX) == 15, "Invalid amount of boxes created for root node. Please update the code above"); + static_assert(static_cast(MaterialGraphBoxes::MAX) == 16, "Invalid amount of boxes created for root node. Please update the code above"); #undef INIT_BOX // Mark as root diff --git a/Source/Shaders/MaterialCommon.hlsl b/Source/Shaders/MaterialCommon.hlsl index 1f516a4fc..01ba12e8c 100644 --- a/Source/Shaders/MaterialCommon.hlsl +++ b/Source/Shaders/MaterialCommon.hlsl @@ -83,9 +83,10 @@ struct Material float Opacity; float3 SubsurfaceColor; float Refraction; + float3 WorldDisplacement; float Mask; float TessellationMultiplier; - float3 WorldDisplacement; + float DepthOffset; #if USE_CUSTOM_VERTEX_INTERPOLATORS float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT]; #endif