Add ShadowsResolution for manually specified shadowmap resolution for lights
This commit is contained in:
@@ -40,6 +40,7 @@ void DirectionalLight::Draw(RenderContext& renderContext)
|
|||||||
data.CastVolumetricShadow = CastVolumetricShadow;
|
data.CastVolumetricShadow = CastVolumetricShadow;
|
||||||
data.ShadowsUpdateRate = ShadowsUpdateRate;
|
data.ShadowsUpdateRate = ShadowsUpdateRate;
|
||||||
data.ShadowFrame = _invalidateShadowFrame;
|
data.ShadowFrame = _invalidateShadowFrame;
|
||||||
|
data.ShadowsResolution = (int32)ShadowsResolution;
|
||||||
data.ShadowsUpdateRateAtDistance = ShadowsUpdateRateAtDistance;
|
data.ShadowsUpdateRateAtDistance = ShadowsUpdateRateAtDistance;
|
||||||
data.ShadowsMode = ShadowsMode;
|
data.ShadowsMode = ShadowsMode;
|
||||||
data.CascadeCount = CascadeCount;
|
data.CascadeCount = CascadeCount;
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public:
|
|||||||
const Vector3 size(50);
|
const Vector3 size(50);
|
||||||
return BoundingBox(_transform.Translation - size, _transform.Translation + size);
|
return BoundingBox(_transform.Translation - size, _transform.Translation + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void DrawLightsDebug(RenderView& view);
|
virtual void DrawLightsDebug(RenderView& view);
|
||||||
#endif
|
#endif
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
@@ -79,6 +79,26 @@ public:
|
|||||||
API_CLASS(Abstract) class FLAXENGINE_API LightWithShadow : public Light
|
API_CLASS(Abstract) class FLAXENGINE_API LightWithShadow : public Light
|
||||||
{
|
{
|
||||||
DECLARE_SCENE_OBJECT_ABSTRACT(LightWithShadow);
|
DECLARE_SCENE_OBJECT_ABSTRACT(LightWithShadow);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of fixed resolutions for light shadow map.
|
||||||
|
/// </summary>
|
||||||
|
API_ENUM() enum class ShadowMapResolution
|
||||||
|
{
|
||||||
|
// Use automatic dynamic resolution based on distance to view.
|
||||||
|
Dynamic = 0,
|
||||||
|
// Shadow map of size 128x128.
|
||||||
|
_128 = 128,
|
||||||
|
// Shadow map of size 256x256.
|
||||||
|
_256 = 256,
|
||||||
|
// Shadow map of size 512x512.
|
||||||
|
_512 = 512,
|
||||||
|
// Shadow map of size 1024x1024.
|
||||||
|
_1024 = 1024,
|
||||||
|
// Shadow map of size 2048x2048.
|
||||||
|
_2048 = 2048,
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32 _invalidateShadowFrame = 0;
|
uint32 _invalidateShadowFrame = 0;
|
||||||
|
|
||||||
@@ -143,12 +163,18 @@ public:
|
|||||||
API_FIELD(Attributes="EditorOrder(105), EditorDisplay(\"Shadow\", \"Update Rate At Distance\"), Limit(0.0f, 1.0f)")
|
API_FIELD(Attributes="EditorOrder(105), EditorDisplay(\"Shadow\", \"Update Rate At Distance\"), Limit(0.0f, 1.0f)")
|
||||||
float ShadowsUpdateRateAtDistance = 0.5f;
|
float ShadowsUpdateRateAtDistance = 0.5f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the resolution of the shadow map texture used to draw objects projection from light-point-of-view. Higher values increase shadow quality at cost of performance.
|
||||||
|
/// </summary>
|
||||||
|
API_FIELD(Attributes="EditorOrder(105), EditorDisplay(\"Shadow\", \"Resolution\")")
|
||||||
|
ShadowMapResolution ShadowsResolution = ShadowMapResolution::Dynamic;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes how a visual element casts shadows.
|
/// Describes how a visual element casts shadows.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_FIELD(Attributes="EditorOrder(60), EditorDisplay(\"Shadow\", \"Mode\")")
|
API_FIELD(Attributes="EditorOrder(60), EditorDisplay(\"Shadow\", \"Mode\")")
|
||||||
ShadowsCastingMode ShadowsMode = ShadowsCastingMode::All;
|
ShadowsCastingMode ShadowsMode = ShadowsCastingMode::All;
|
||||||
|
|
||||||
/// <summary>
|
/// <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).
|
/// 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>
|
/// </summary>
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ void PointLight::Draw(RenderContext& renderContext)
|
|||||||
data.ShadowsUpdateRate = ShadowsUpdateRate;
|
data.ShadowsUpdateRate = ShadowsUpdateRate;
|
||||||
data.ShadowsUpdateRateAtDistance = ShadowsUpdateRateAtDistance;
|
data.ShadowsUpdateRateAtDistance = ShadowsUpdateRateAtDistance;
|
||||||
data.ShadowFrame = _invalidateShadowFrame;
|
data.ShadowFrame = _invalidateShadowFrame;
|
||||||
|
data.ShadowsResolution = (int32)ShadowsResolution;
|
||||||
data.ShadowsMode = ShadowsMode;
|
data.ShadowsMode = ShadowsMode;
|
||||||
data.Radius = radius;
|
data.Radius = radius;
|
||||||
data.FallOffExponent = FallOffExponent;
|
data.FallOffExponent = FallOffExponent;
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ void SpotLight::Draw(RenderContext& renderContext)
|
|||||||
data.ShadowsUpdateRate = ShadowsUpdateRate;
|
data.ShadowsUpdateRate = ShadowsUpdateRate;
|
||||||
data.ShadowsUpdateRateAtDistance = ShadowsUpdateRateAtDistance;
|
data.ShadowsUpdateRateAtDistance = ShadowsUpdateRateAtDistance;
|
||||||
data.ShadowFrame = _invalidateShadowFrame;
|
data.ShadowFrame = _invalidateShadowFrame;
|
||||||
|
data.ShadowsResolution = (int32)ShadowsResolution;
|
||||||
data.ShadowsMode = ShadowsMode;
|
data.ShadowsMode = ShadowsMode;
|
||||||
data.Radius = radius;
|
data.Radius = radius;
|
||||||
data.FallOffExponent = FallOffExponent;
|
data.FallOffExponent = FallOffExponent;
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ struct RenderLightData
|
|||||||
float ShadowsUpdateRate;
|
float ShadowsUpdateRate;
|
||||||
float ShadowsUpdateRateAtDistance;
|
float ShadowsUpdateRateAtDistance;
|
||||||
uint32 ShadowFrame;
|
uint32 ShadowFrame;
|
||||||
|
int32 ShadowsResolution;
|
||||||
|
|
||||||
bool CanRenderShadow(const RenderView& view) const;
|
bool CanRenderShadow(const RenderView& view) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ struct ShadowAtlasLightCache
|
|||||||
float Distance;
|
float Distance;
|
||||||
Float4 CascadeSplits;
|
Float4 CascadeSplits;
|
||||||
Float3 ViewDirection;
|
Float3 ViewDirection;
|
||||||
|
int32 ShadowsResolution;
|
||||||
|
|
||||||
void Set(const RenderView& view, const RenderLightData& light, const Float4& cascadeSplits = Float4::Zero)
|
void Set(const RenderView& view, const RenderLightData& light, const Float4& cascadeSplits = Float4::Zero)
|
||||||
{
|
{
|
||||||
@@ -152,6 +153,7 @@ struct ShadowAtlasLightCache
|
|||||||
ShadowsUpdateRateAtDistance = light.ShadowsUpdateRateAtDistance;
|
ShadowsUpdateRateAtDistance = light.ShadowsUpdateRateAtDistance;
|
||||||
Direction = light.Direction;
|
Direction = light.Direction;
|
||||||
ShadowFrame = light.ShadowFrame;
|
ShadowFrame = light.ShadowFrame;
|
||||||
|
ShadowsResolution = light.ShadowsResolution;
|
||||||
if (light.IsDirectionalLight)
|
if (light.IsDirectionalLight)
|
||||||
{
|
{
|
||||||
// Sun
|
// Sun
|
||||||
@@ -247,6 +249,7 @@ struct ShadowAtlasLight
|
|||||||
!Math::NearEqual(Cache.ShadowsUpdateRate, light.ShadowsUpdateRate) ||
|
!Math::NearEqual(Cache.ShadowsUpdateRate, light.ShadowsUpdateRate) ||
|
||||||
!Math::NearEqual(Cache.ShadowsUpdateRateAtDistance, light.ShadowsUpdateRateAtDistance) ||
|
!Math::NearEqual(Cache.ShadowsUpdateRateAtDistance, light.ShadowsUpdateRateAtDistance) ||
|
||||||
Cache.ShadowFrame != light.ShadowFrame ||
|
Cache.ShadowFrame != light.ShadowFrame ||
|
||||||
|
Cache.ShadowsResolution != light.ShadowsResolution ||
|
||||||
Float3::Dot(Cache.Direction, light.Direction) < SHADOWS_ROTATION_ERROR)
|
Float3::Dot(Cache.Direction, light.Direction) < SHADOWS_ROTATION_ERROR)
|
||||||
{
|
{
|
||||||
// Invalidate
|
// Invalidate
|
||||||
@@ -1119,9 +1122,12 @@ void ShadowsPass::SetupShadows(RenderContext& renderContext, RenderContextBatch&
|
|||||||
auto& atlasLight = shadows.Lights[light->ID];
|
auto& atlasLight = shadows.Lights[light->ID];
|
||||||
|
|
||||||
// Calculate resolution for this light
|
// Calculate resolution for this light
|
||||||
// TODO: add support for fixed shadow map resolution assigned per-light
|
atlasLight.Resolution = light->ShadowsResolution;
|
||||||
float lightResolutionFloat = baseLightResolution * light->ScreenSize;
|
if (atlasLight.Resolution == 0)
|
||||||
atlasLight.Resolution = QuantizeResolution(lightResolutionFloat);
|
{
|
||||||
|
// ScreenSize-based automatic shadowmap resolution
|
||||||
|
atlasLight.Resolution = QuantizeResolution(baseLightResolution * light->ScreenSize);
|
||||||
|
}
|
||||||
|
|
||||||
// Cull too small lights
|
// Cull too small lights
|
||||||
if (atlasLight.Resolution < SHADOWS_MIN_RESOLUTION)
|
if (atlasLight.Resolution < SHADOWS_MIN_RESOLUTION)
|
||||||
|
|||||||
Reference in New Issue
Block a user