Add InvalidateShadow for manual shadow cache refresh

This commit is contained in:
Wojtek Figat
2024-04-11 16:34:42 +02:00
parent 803249f126
commit a532ea7b42
7 changed files with 20 additions and 0 deletions

View File

@@ -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;

View File

@@ -84,6 +84,11 @@ LightWithShadow::LightWithShadow(const SpawnParams& params)
{
}
void LightWithShadow::InvalidateShadow()
{
_invalidateShadowFrame++;
}
void LightWithShadow::Serialize(SerializeStream& stream, const void* otherObj)
{
// Base

View File

@@ -79,6 +79,9 @@ public:
API_CLASS(Abstract) class FLAXENGINE_API LightWithShadow : public Light
{
DECLARE_SCENE_OBJECT_ABSTRACT(LightWithShadow);
protected:
uint32 _invalidateShadowFrame = 0;
public:
/// <summary>
/// The minimum roughness value used to clamp material surface roughness during shading pixel.
@@ -145,6 +148,11 @@ public:
/// </summary>
API_FIELD(Attributes="EditorOrder(60), EditorDisplay(\"Shadow\", \"Mode\")")
ShadowsCastingMode ShadowsMode = ShadowsCastingMode::All;
/// <summary>
/// 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).
/// </summary>
API_FUNCTION() void InvalidateShadow();
public:
// [Light]

View File

@@ -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;

View File

@@ -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;

View File

@@ -58,6 +58,7 @@ struct RenderLightData
float ShadowsUpdateRate;
float ShadowsUpdateRateAtDistance;
uint32 ShadowFrame;
bool CanRenderShadow(const RenderView& view) const;
};

View File

@@ -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