diff --git a/Source/Engine/Level/Actors/DirectionalLight.cpp b/Source/Engine/Level/Actors/DirectionalLight.cpp index 3d198e042..cef1eba97 100644 --- a/Source/Engine/Level/Actors/DirectionalLight.cpp +++ b/Source/Engine/Level/Actors/DirectionalLight.cpp @@ -39,6 +39,7 @@ void DirectionalLight::Draw(RenderContext& renderContext) data.IndirectLightingIntensity = IndirectLightingIntensity; data.CastVolumetricShadow = CastVolumetricShadow; data.ShadowsUpdateRate = ShadowsUpdateRate; + data.ShadowFrame = _invalidateShadowFrame; data.ShadowsUpdateRateAtDistance = ShadowsUpdateRateAtDistance; data.ShadowsMode = ShadowsMode; data.CascadeCount = CascadeCount; diff --git a/Source/Engine/Level/Actors/Light.cpp b/Source/Engine/Level/Actors/Light.cpp index 6a0dfa726..81aeb2e4a 100644 --- a/Source/Engine/Level/Actors/Light.cpp +++ b/Source/Engine/Level/Actors/Light.cpp @@ -84,6 +84,11 @@ LightWithShadow::LightWithShadow(const SpawnParams& params) { } +void LightWithShadow::InvalidateShadow() +{ + _invalidateShadowFrame++; +} + void LightWithShadow::Serialize(SerializeStream& stream, const void* otherObj) { // Base diff --git a/Source/Engine/Level/Actors/Light.h b/Source/Engine/Level/Actors/Light.h index afe644c27..8fd40c530 100644 --- a/Source/Engine/Level/Actors/Light.h +++ b/Source/Engine/Level/Actors/Light.h @@ -79,6 +79,9 @@ public: API_CLASS(Abstract) class FLAXENGINE_API LightWithShadow : public Light { DECLARE_SCENE_OBJECT_ABSTRACT(LightWithShadow); +protected: + uint32 _invalidateShadowFrame = 0; + public: /// /// The minimum roughness value used to clamp material surface roughness during shading pixel. @@ -145,6 +148,11 @@ public: /// API_FIELD(Attributes="EditorOrder(60), EditorDisplay(\"Shadow\", \"Mode\")") ShadowsCastingMode ShadowsMode = ShadowsCastingMode::All; + + /// + /// Marks the light shadow to be refreshes during next drawing. Invalidates any cached shadow map and redraws static shadows of the object (if any in use). + /// + API_FUNCTION() void InvalidateShadow(); public: // [Light] diff --git a/Source/Engine/Level/Actors/PointLight.cpp b/Source/Engine/Level/Actors/PointLight.cpp index 626008a54..5f2be645b 100644 --- a/Source/Engine/Level/Actors/PointLight.cpp +++ b/Source/Engine/Level/Actors/PointLight.cpp @@ -105,6 +105,7 @@ void PointLight::Draw(RenderContext& renderContext) data.CastVolumetricShadow = CastVolumetricShadow; data.ShadowsUpdateRate = ShadowsUpdateRate; data.ShadowsUpdateRateAtDistance = ShadowsUpdateRateAtDistance; + data.ShadowFrame = _invalidateShadowFrame; data.ShadowsMode = ShadowsMode; data.Radius = radius; data.FallOffExponent = FallOffExponent; diff --git a/Source/Engine/Level/Actors/SpotLight.cpp b/Source/Engine/Level/Actors/SpotLight.cpp index f2b6046ee..892bdf02e 100644 --- a/Source/Engine/Level/Actors/SpotLight.cpp +++ b/Source/Engine/Level/Actors/SpotLight.cpp @@ -155,6 +155,7 @@ void SpotLight::Draw(RenderContext& renderContext) data.CastVolumetricShadow = CastVolumetricShadow; data.ShadowsUpdateRate = ShadowsUpdateRate; data.ShadowsUpdateRateAtDistance = ShadowsUpdateRateAtDistance; + data.ShadowFrame = _invalidateShadowFrame; data.ShadowsMode = ShadowsMode; data.Radius = radius; data.FallOffExponent = FallOffExponent; diff --git a/Source/Engine/Renderer/RenderList.h b/Source/Engine/Renderer/RenderList.h index a58eeb0c4..0fe3bc960 100644 --- a/Source/Engine/Renderer/RenderList.h +++ b/Source/Engine/Renderer/RenderList.h @@ -58,6 +58,7 @@ struct RenderLightData float ShadowsUpdateRate; float ShadowsUpdateRateAtDistance; + uint32 ShadowFrame; bool CanRenderShadow(const RenderView& view) const; }; diff --git a/Source/Engine/Renderer/ShadowsPass.cpp b/Source/Engine/Renderer/ShadowsPass.cpp index 32ec246aa..d6a40238a 100644 --- a/Source/Engine/Renderer/ShadowsPass.cpp +++ b/Source/Engine/Renderer/ShadowsPass.cpp @@ -121,6 +121,7 @@ struct ShadowAtlasLightCache bool DynamicValid; float ShadowsUpdateRate; float ShadowsUpdateRateAtDistance; + uint32 ShadowFrame; float OuterConeAngle; Float3 Position; float Radius; @@ -136,6 +137,7 @@ struct ShadowAtlasLightCache ShadowsUpdateRate = light.ShadowsUpdateRate; ShadowsUpdateRateAtDistance = light.ShadowsUpdateRateAtDistance; Direction = light.Direction; + ShadowFrame = light.ShadowFrame; if (light.IsDirectionalLight) { // Sun @@ -229,6 +231,7 @@ struct ShadowAtlasLight if (!Math::NearEqual(Cache.Distance, light.ShadowsDistance) || !Math::NearEqual(Cache.ShadowsUpdateRate, light.ShadowsUpdateRate) || !Math::NearEqual(Cache.ShadowsUpdateRateAtDistance, light.ShadowsUpdateRateAtDistance) || + Cache.ShadowFrame != light.ShadowFrame || Float3::Dot(Cache.Direction, light.Direction) < 0.999999f) { // Invalidate