diff --git a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl index 50cf52bbf..87b26809b 100644 --- a/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl +++ b/Content/Editor/MaterialTemplates/Features/ForwardShading.hlsl @@ -97,6 +97,11 @@ float4 PS_Forward(PixelInput input) : SV_Target0 light += GetLighting(ViewPos, localLight, gBuffer, shadowMask, true, isSpotLight); } + // Calculate lighting from Global Illumination +#if USE_GI + light += GetGlobalIlluminationLighting(gBuffer); +#endif + // Calculate reflections #if USE_REFLECTIONS float3 reflections = SampleReflectionProbe(ViewPos, EnvProbe, EnvironmentProbe, gBuffer.WorldPos, gBuffer.Normal, gBuffer.Roughness).rgb; diff --git a/Content/Editor/MaterialTemplates/Features/GlobalIllumination.hlsl b/Content/Editor/MaterialTemplates/Features/GlobalIllumination.hlsl new file mode 100644 index 000000000..7159f1423 --- /dev/null +++ b/Content/Editor/MaterialTemplates/Features/GlobalIllumination.hlsl @@ -0,0 +1,23 @@ +// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. + +@0// Global Illumination: Defines +#define USE_GI 1 +@1// Global Illumination: Includes +#include "./Flax/GI/DDGI.hlsl" +#include "./Flax/LightingCommon.hlsl" +@2// Global Illumination: Constants +DDGIData DDGI; +@3// Global Illumination: Resources +Texture2D ProbesState : register(t__SRV__); +Texture2D ProbesDistance : register(t__SRV__); +Texture2D ProbesIrradiance : register(t__SRV__); +@4// Global Illumination: Utilities +float4 GetGlobalIlluminationLighting(GBufferSample gBuffer) +{ + float3 irradiance = SampleDDGIIrradiance(DDGI, ProbesState, ProbesDistance, ProbesIrradiance, gBuffer.WorldPos, gBuffer.Normal); + float3 diffuseColor = GetDiffuseColor(gBuffer); + float3 diffuse = Diffuse_Lambert(diffuseColor); + return float4(diffuse * irradiance, saturate(length(irradiance))); +} + +@5// Global Illumination: Shaders diff --git a/Content/Editor/Particles/Smoke Material.flax b/Content/Editor/Particles/Smoke Material.flax index ee5d1f2eb..319c8a424 100644 --- a/Content/Editor/Particles/Smoke Material.flax +++ b/Content/Editor/Particles/Smoke Material.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:015cfb4b86b9f38833007a209e5ef345ad351d868e18335cc423892945bb3b1b -size 37177 +oid sha256:6524e211d8bb80cf654f30a09e4f99da5a1775bca1cd319e256014e1e71e10d9 +size 38134 diff --git a/Source/Editor/Windows/Assets/MaterialWindow.cs b/Source/Editor/Windows/Assets/MaterialWindow.cs index 2cad5dfca..cabead5b6 100644 --- a/Source/Editor/Windows/Assets/MaterialWindow.cs +++ b/Source/Editor/Windows/Assets/MaterialWindow.cs @@ -94,6 +94,9 @@ namespace FlaxEditor.Windows.Assets [EditorOrder(220), DefaultValue(true), EditorDisplay("Transparency"), Tooltip("Enables distortion effect when rendering.")] public bool EnableDistortion; + [EditorOrder(224), DefaultValue(false), EditorDisplay("Transparency"), Tooltip("Enables sampling Global Illumination in material (eg. light probes or volumetric lightmap).")] + public bool EnableGlobalIllumination; + [EditorOrder(225), DefaultValue(false), EditorDisplay("Transparency"), Tooltip("Enables refraction offset based on the difference between the per-pixel normal and the per-vertex normal. Useful for large water-like surfaces.")] public bool PixelNormalOffsetRefraction; @@ -156,6 +159,7 @@ namespace FlaxEditor.Windows.Assets EnableScreenSpaceReflections = (info.FeaturesFlags & MaterialFeaturesFlags.ScreenSpaceReflections) != 0; EnableFog = (info.FeaturesFlags & MaterialFeaturesFlags.DisableFog) == 0; EnableDistortion = (info.FeaturesFlags & MaterialFeaturesFlags.DisableDistortion) == 0; + EnableGlobalIllumination = (info.FeaturesFlags & MaterialFeaturesFlags.GlobalIllumination) != 0; PixelNormalOffsetRefraction = (info.FeaturesFlags & MaterialFeaturesFlags.PixelNormalOffsetRefraction) != 0; InputWorldSpaceNormal = (info.FeaturesFlags & MaterialFeaturesFlags.InputWorldSpaceNormal) != 0; DitheredLODTransition = (info.FeaturesFlags & MaterialFeaturesFlags.DitheredLODTransition) != 0; @@ -196,6 +200,8 @@ namespace FlaxEditor.Windows.Assets info.FeaturesFlags |= MaterialFeaturesFlags.DisableFog; if (!EnableDistortion) info.FeaturesFlags |= MaterialFeaturesFlags.DisableDistortion; + if (EnableGlobalIllumination) + info.FeaturesFlags |= MaterialFeaturesFlags.GlobalIllumination; if (PixelNormalOffsetRefraction) info.FeaturesFlags |= MaterialFeaturesFlags.PixelNormalOffsetRefraction; if (InputWorldSpaceNormal) diff --git a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp index c8aa7dd87..67f0914a1 100644 --- a/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/ForwardMaterialShader.cpp @@ -64,6 +64,8 @@ void ForwardMaterialShader::Bind(BindParameters& params) int32 srv = 2; // Setup features + if (_info.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) + GlobalIlluminationFeature::Bind(params, cb, srv); ForwardShadingFeature::Bind(params, cb, srv); // Setup parameters diff --git a/Source/Engine/Graphics/Materials/MaterialInfo.h b/Source/Engine/Graphics/Materials/MaterialInfo.h index 3bf12ca7c..876246e0c 100644 --- a/Source/Engine/Graphics/Materials/MaterialInfo.h +++ b/Source/Engine/Graphics/Materials/MaterialInfo.h @@ -277,6 +277,11 @@ API_ENUM(Attributes="Flags") enum class MaterialFeaturesFlags : uint32 /// The flag used to enable high-quality reflections based on the screen space raytracing. Useful for large water-like surfaces. The Forward Pass materials option. /// ScreenSpaceReflections = 1 << 10, + + /// + /// The flag used to enable sampling Global Illumination in material (eg. light probes or volumetric lightmap). The Forward Pass materials option. + /// + GlobalIllumination = 1 << 11, }; DECLARE_ENUM_OPERATORS(MaterialFeaturesFlags); diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp index 8debde3eb..44e3af4c6 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.cpp @@ -154,6 +154,48 @@ bool LightmapFeature::Bind(MaterialShader::BindParameters& params, Span& c return useLightmap; } +bool GlobalIlluminationFeature::Bind(MaterialShader::BindParameters& params, Span& cb, int32& srv) +{ + auto& data = *(Data*)cb.Get(); + ASSERT_LOW_LAYER(cb.Length() >= sizeof(Data)); + + bool useGI = false; + if (params.RenderContext.View.Flags & ViewFlags::GI) + { + switch (params.RenderContext.List->Settings.GlobalIllumination.Mode) + { + case GlobalIlluminationMode::DDGI: + { + DynamicDiffuseGlobalIlluminationPass::BindingData bindingDataDDGI; + if (!DynamicDiffuseGlobalIlluminationPass::Instance()->Get(params.RenderContext.Buffers, bindingDataDDGI)) + { + useGI = true; + + // Bind DDGI data + data.DDGI = bindingDataDDGI.Constants; + params.GPUContext->BindSR(srv + 0, bindingDataDDGI.ProbesState); + params.GPUContext->BindSR(srv + 1, bindingDataDDGI.ProbesDistance); + params.GPUContext->BindSR(srv + 2, bindingDataDDGI.ProbesIrradiance); + } + break; + } + } + } + if (!useGI) + { + // Unbind SRVs to prevent issues + data.DDGI.CascadesCount = 0; + data.DDGI.FallbackIrradiance = Float3::Zero; + params.GPUContext->UnBindSR(srv + 0); + params.GPUContext->UnBindSR(srv + 1); + params.GPUContext->UnBindSR(srv + 2); + } + + cb = Span(cb.Get() + sizeof(Data), cb.Length() - sizeof(Data)); + srv += SRVs; + return useGI; +} + #if USE_EDITOR void ForwardShadingFeature::Generate(GeneratorData& data) @@ -176,6 +218,11 @@ void LightmapFeature::Generate(GeneratorData& data) data.Template = TEXT("Features/Lightmap.hlsl"); } +void GlobalIlluminationFeature::Generate(GeneratorData& data) +{ + data.Template = TEXT("Features/GlobalIllumination.hlsl"); +} + void DistortionFeature::Generate(GeneratorData& data) { data.Template = TEXT("Features/Distortion.hlsl"); diff --git a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h index 7add4aa05..e4d222ef7 100644 --- a/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h +++ b/Source/Engine/Graphics/Materials/MaterialShaderFeatures.h @@ -5,6 +5,7 @@ #include "MaterialShader.h" #include "Engine/Core/Math/Rectangle.h" #include "Engine/Core/Types/Span.h" +#include "Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h" // Material shader features are plugin-based functionalities that are reusable between different material domains. struct MaterialShaderFeature @@ -74,6 +75,22 @@ struct LightmapFeature : MaterialShaderFeature #endif }; +// Material shader feature that adds Global Illumination sampling feature (light probes). +struct GlobalIlluminationFeature : MaterialShaderFeature +{ + enum { SRVs = 3 }; + + PACK_STRUCT(struct Data + { + DynamicDiffuseGlobalIlluminationPass::ConstantsData DDGI; + }); + + static bool Bind(MaterialShader::BindParameters& params, Span& cb, int32& srv); +#if USE_EDITOR + static void Generate(GeneratorData& data); +#endif +}; + // Material shader feature that adds distortion vectors rendering pass. struct DistortionFeature : MaterialShaderFeature { diff --git a/Source/Engine/Graphics/Materials/ParticleMaterialShader.cpp b/Source/Engine/Graphics/Materials/ParticleMaterialShader.cpp index 43c8c2f19..196108608 100644 --- a/Source/Engine/Graphics/Materials/ParticleMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/ParticleMaterialShader.cpp @@ -64,6 +64,8 @@ void ParticleMaterialShader::Bind(BindParameters& params) int32 srv = 2; // Setup features + if (_info.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) + GlobalIlluminationFeature::Bind(params, cb, srv); ForwardShadingFeature::Bind(params, cb, srv); // Setup parameters diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp index 28df658ae..9b8812eee 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp @@ -197,6 +197,8 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo ADD_FEATURE(DeferredShadingFeature); if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == 0) ADD_FEATURE(DistortionFeature); + if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) != 0) + ADD_FEATURE(GlobalIlluminationFeature); if (materialInfo.BlendMode != MaterialBlendMode::Opaque) ADD_FEATURE(ForwardShadingFeature); break; @@ -209,6 +211,8 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo case MaterialDomain::Particle: if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::DisableDistortion) == 0) ADD_FEATURE(DistortionFeature); + if (materialInfo.BlendMode != MaterialBlendMode::Opaque && (materialInfo.FeaturesFlags & MaterialFeaturesFlags::GlobalIllumination) != 0) + ADD_FEATURE(GlobalIlluminationFeature); ADD_FEATURE(ForwardShadingFeature); break; case MaterialDomain::Deformable: