diff --git a/Source/Engine/Graphics/PostProcessSettings.cpp b/Source/Engine/Graphics/PostProcessSettings.cpp index 7c728bcf7..51281dba0 100644 --- a/Source/Engine/Graphics/PostProcessSettings.cpp +++ b/Source/Engine/Graphics/PostProcessSettings.cpp @@ -33,6 +33,7 @@ void GlobalIlluminationSettings::BlendWith(GlobalIlluminationSettings& other, fl BLEND_FLOAT(BounceIntensity); BLEND_FLOAT(TemporalResponse); BLEND_FLOAT(Distance); + BLEND_FLOAT(IndirectShadowsStrength); BLEND_COL(FallbackIrradiance); } diff --git a/Source/Engine/Graphics/PostProcessSettings.h b/Source/Engine/Graphics/PostProcessSettings.h index 20d886fa3..f9ae1a53b 100644 --- a/Source/Engine/Graphics/PostProcessSettings.h +++ b/Source/Engine/Graphics/PostProcessSettings.h @@ -334,10 +334,15 @@ API_ENUM(Attributes="Flags") enum class GlobalIlluminationSettingsOverride : int /// BounceIntensity = 1 << 5, + /// + /// Overrides property. + /// + IndirectShadowsStrength = 1 << 6, + /// /// All properties. /// - All = Mode | Intensity | TemporalResponse | Distance | FallbackIrradiance | BounceIntensity, + All = Mode | Intensity | TemporalResponse | Distance | FallbackIrradiance | BounceIntensity | IndirectShadowsStrength, }; /// @@ -385,6 +390,12 @@ API_STRUCT() struct FLAXENGINE_API GlobalIlluminationSettings : ISerializable API_FIELD(Attributes="EditorOrder(30), Limit(1000), PostProcessSetting((int)GlobalIlluminationSettingsOverride.Distance), ValueCategory(Utils.ValueCategory.Distance)") float Distance = 20000.0f; + /// + /// Indirect lighting shadows intensity. Default is 1 for fully opaque shadowing, lower values bleed the lighting into shadowed areas. Can be sued for artistic control over GI. + /// + API_FIELD(Attributes = "EditorOrder(35), Limit(0.0f, 1.0f, 0.001f), PostProcessSetting((int)GlobalIlluminationSettingsOverride.IndirectShadowsStrength)") + float IndirectShadowsStrength = 1.0f; + /// /// The irradiance lighting outside the GI range used as a fallback to prevent pure-black scene outside the Global Illumination range. /// diff --git a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp index 22b063d4e..00127fbc9 100644 --- a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp +++ b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.cpp @@ -546,6 +546,7 @@ bool DynamicDiffuseGlobalIlluminationPass::RenderInner(RenderContext& renderCont ddgiData.Result.Constants.RaysCount = probeRaysCount; ddgiData.Result.Constants.ProbeHistoryWeight = probeHistoryWeight; ddgiData.Result.Constants.IndirectLightingIntensity = indirectLightingIntensity; + ddgiData.Result.Constants.IndirectShadowsStrength = settings.IndirectShadowsStrength; ddgiData.Result.Constants.FallbackIrradiance = settings.FallbackIrradiance.ToFloat4(); ddgiData.Result.ProbesData = ddgiData.ProbesData->View(); ddgiData.Result.ProbesDistance = ddgiData.ProbesDistance->View(); diff --git a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h index 0e4c2612d..d58eee47a 100644 --- a/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h +++ b/Source/Engine/Renderer/GI/DynamicDiffuseGlobalIllumination.h @@ -19,10 +19,10 @@ public: Int4 ProbesScrollOffsets[4]; // w is unused uint32 ProbesCounts[3]; uint32 CascadesCount; - float Padding; float ProbeHistoryWeight; float RayMaxDistance; float IndirectLightingIntensity; + float IndirectShadowsStrength; Float3 ViewPos; uint32 RaysCount; Float4 FallbackIrradiance; diff --git a/Source/Shaders/GI/DDGI.hlsl b/Source/Shaders/GI/DDGI.hlsl index 718fd2aaa..88b9a4cb8 100644 --- a/Source/Shaders/GI/DDGI.hlsl +++ b/Source/Shaders/GI/DDGI.hlsl @@ -41,10 +41,10 @@ struct DDGIData int4 ProbesScrollOffsets[4]; // w is unused uint3 ProbesCounts; uint CascadesCount; - float Padding; float ProbeHistoryWeight; float RayMaxDistance; float IndirectLightingIntensity; + float IndirectShadowsStrength; float3 ViewPos; uint RaysCount; float4 FallbackIrradiance; @@ -245,6 +245,7 @@ float3 SampleDDGIIrradianceCascade(DDGIData data, Texture2D probes { float variance = abs(Square(probeDistance.x) - probeDistance.y); float visibilityWeight = variance / (variance + Square(biasedPosToProbeDist - probeDistance.x)); + visibilityWeight = lerp(1, visibilityWeight, data.IndirectShadowsStrength); weights *= max(visibilityWeight * visibilityWeight * visibilityWeight, 0.0f); } @@ -294,7 +295,8 @@ float3 SampleDDGIIrradianceCascade(DDGIData data, Texture2D probes #if !DDGI_FALLBACK_OUTER_DEDICATED_PROBE canNormalize += invalidCascade ? 1 : 0; // Normalize when outside the last cascade to preserve ambient GI when not using ambient probe #endif - totalIrradiance.rgb /= lerp(1, totalIrradiance.a, saturate(canNormalize)); + float shadowNormalization = lerp(1, totalIrradiance.a, saturate(canNormalize)); + totalIrradiance.rgb /= lerp(totalIrradiance.a, shadowNormalization, data.IndirectShadowsStrength); if (fallbacks >= 5 && totalIrradianceNonDir.a > 0.00001f) { // Use non-directional irradiance when sampling mostly fallback probes (out of place)