From 817da70b99e000d65703b5450c11cac63cc2e27b Mon Sep 17 00:00:00 2001 From: Eideren Date: Wed, 29 May 2024 22:50:27 +0200 Subject: [PATCH] [Graphics] Fix light component API (#2215) --- .../Rendering/Lights/DirectLightBase.cs | 30 ------------------- .../Rendering/Lights/LightDirectional.cs | 20 +++++++++---- .../Rendering/Lights/LightPoint.cs | 20 +++++++++---- .../Rendering/Lights/LightSpot.cs | 18 ++++++++--- .../LightDirectionalShadowMapRenderer.cs | 2 +- .../LightPointShadowMapRendererCubeMap.cs | 7 ++--- .../LightPointShadowMapRendererParaboloid.cs | 16 ++++------ 7 files changed, 54 insertions(+), 59 deletions(-) delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/DirectLightBase.cs diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightBase.cs b/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightBase.cs deleted file mode 100644 index a66fa885b4..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightBase.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; -using Stride.Core.Mathematics; -using Stride.Engine; - -namespace Stride.Rendering.Lights -{ - /// - /// Base implementation of . - /// - [DataContract] - public abstract class DirectLightBase : ColorLightBase, IDirectLight - { - /// - /// Gets or sets the shadow. - /// - /// The shadow. - /// The settings of the light shadow - [DataMember(200)] - public LightShadowMap Shadow { get; protected set; } - - public abstract bool HasBoundingBox { get; } - - public abstract BoundingBox ComputeBounds(Vector3 position, Vector3 direction); - - public abstract float ComputeScreenCoverage(RenderView renderView, Vector3 position, Vector3 direction); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightDirectional.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightDirectional.cs index bf3bd171fb..717e0269a7 100644 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightDirectional.cs +++ b/sources/engine/Stride.Rendering/Rendering/Lights/LightDirectional.cs @@ -14,17 +14,25 @@ namespace Stride.Rendering.Lights /// [DataContract("LightDirectional")] [Display("Directional")] - public class LightDirectional : DirectLightBase + public class LightDirectional : ColorLightBase, IDirectLight { + /// + /// Gets or sets the shadow. + /// + /// The shadow. + /// The settings of the light shadow + [DataMember(200)] + public LightDirectionalShadowMap Shadow { get; set; } + public LightDirectional() { - Shadow = new LightDirectionalShadowMap + Shadow = new() { Size = LightShadowMapSize.Large, }; } - public override bool HasBoundingBox + public bool HasBoundingBox { get { @@ -32,12 +40,12 @@ public override bool HasBoundingBox } } - public override BoundingBox ComputeBounds(Vector3 position, Vector3 direction) + public BoundingBox ComputeBounds(Vector3 position, Vector3 direction) { return BoundingBox.Empty; } - public override float ComputeScreenCoverage(RenderView renderView, Vector3 position, Vector3 direction) + public float ComputeScreenCoverage(RenderView renderView, Vector3 position, Vector3 direction) { // As the directional light is covering the whole screen, we take the max of current width, height return Math.Max(renderView.ViewSize.X, renderView.ViewSize.Y); @@ -47,5 +55,7 @@ public override bool Update(RenderLight light) { return true; } + + LightShadowMap IDirectLight.Shadow => Shadow; } } diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightPoint.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightPoint.cs index 0bac8cab17..65e6bed14b 100644 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightPoint.cs +++ b/sources/engine/Stride.Rendering/Rendering/Lights/LightPoint.cs @@ -15,7 +15,7 @@ namespace Stride.Rendering.Lights /// [DataContract("LightPoint")] [Display("Point")] - public class LightPoint : DirectLightBase + public class LightPoint : ColorLightBase, IDirectLight { /// /// Initializes a new instance of the class. @@ -23,7 +23,7 @@ public class LightPoint : DirectLightBase public LightPoint() { Radius = 1.0f; - Shadow = new LightPointShadowMap() + Shadow = new() { Size = LightShadowMapSize.Small, Type = LightPointShadowMapType.CubeMap, @@ -42,7 +42,15 @@ public LightPoint() [DataMemberIgnore] internal float InvSquareRadius; - public override bool HasBoundingBox + /// + /// Gets or sets the shadow. + /// + /// The shadow. + /// The settings of the light shadow + [DataMember(200)] + public LightPointShadowMap Shadow { get; set; } + + public bool HasBoundingBox { get { @@ -57,12 +65,12 @@ public override bool Update(RenderLight light) return true; } - public override BoundingBox ComputeBounds(Vector3 positionWS, Vector3 directionWS) + public BoundingBox ComputeBounds(Vector3 positionWS, Vector3 directionWS) { return new BoundingBox(positionWS - Radius, positionWS + Radius); } - public override float ComputeScreenCoverage(RenderView renderView, Vector3 position, Vector3 direction) + public float ComputeScreenCoverage(RenderView renderView, Vector3 position, Vector3 direction) { // http://stackoverflow.com/questions/21648630/radius-of-projected-sphere-in-screen-space var targetPosition = new Vector4(position, 1.0f); @@ -82,5 +90,7 @@ public override float ComputeScreenCoverage(RenderView renderView, Vector3 posit // Size on screen return (float)pr * Math.Max(renderView.ViewSize.X, renderView.ViewSize.Y); } + + LightShadowMap IDirectLight.Shadow => Shadow; } } diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightSpot.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightSpot.cs index aac58e6877..e1a9347a70 100644 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightSpot.cs +++ b/sources/engine/Stride.Rendering/Rendering/Lights/LightSpot.cs @@ -17,7 +17,7 @@ namespace Stride.Rendering.Lights /// [DataContract("LightSpot")] [Display("Spot")] - public class LightSpot : DirectLightBase + public class LightSpot : ColorLightBase, IDirectLight { // These values have to match the ones defined in "TextureProjectionReceiverBase.sdsl". public enum FlipModeEnum @@ -158,7 +158,15 @@ public override bool Update(RenderLight light) return true; } - public override bool HasBoundingBox + /// + /// Gets or sets the shadow. + /// + /// The shadow. + /// The settings of the light shadow + [DataMember(200)] + public LightStandardShadowMap Shadow { get; set; } + + public bool HasBoundingBox { get { @@ -166,7 +174,7 @@ public override bool HasBoundingBox } } - public override BoundingBox ComputeBounds(Vector3 position, Vector3 direction) + public BoundingBox ComputeBounds(Vector3 position, Vector3 direction) { // Calculates the bouding box of the spot target var spotTarget = position + direction * Range; @@ -178,7 +186,7 @@ public override BoundingBox ComputeBounds(Vector3 position, Vector3 direction) return box; } - public override float ComputeScreenCoverage(RenderView renderView, Vector3 position, Vector3 direction) + public float ComputeScreenCoverage(RenderView renderView, Vector3 position, Vector3 direction) { // TODO: We could improve this by calculating a screen-aligned triangle and a sphere at the end of the cone. // With the screen-aligned triangle we would cover the entire spotlight, not just its end. @@ -204,5 +212,7 @@ public override float ComputeScreenCoverage(RenderView renderView, Vector3 posit // Size on screen return (float)pr * Math.Max(renderView.ViewSize.X, renderView.ViewSize.Y); } + + LightShadowMap IDirectLight.Shadow => Shadow; } } diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/LightDirectionalShadowMapRenderer.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/LightDirectionalShadowMapRenderer.cs index 2fff609604..387ff0ff18 100644 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/LightDirectionalShadowMapRenderer.cs +++ b/sources/engine/Stride.Rendering/Rendering/Shadows/LightDirectionalShadowMapRenderer.cs @@ -104,7 +104,7 @@ public override bool CanRenderLight(IDirectLight light) public override LightShadowMapTexture CreateShadowMapTexture(RenderView renderView, RenderLight renderLight, IDirectLight light, int shadowMapSize) { var shadowMap = base.CreateShadowMapTexture(renderView, renderLight, light, shadowMapSize); - shadowMap.CascadeCount = ((LightDirectionalShadowMap)light.Shadow).GetCascadeCount(); + shadowMap.CascadeCount = ((LightDirectional)light).Shadow.GetCascadeCount(); // Views with orthographic cameras cannot use cascades, we force it to 1 shadow map here. if (renderView.Projection.M44 == 1.0f) { diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/LightPointShadowMapRendererCubeMap.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/LightPointShadowMapRendererCubeMap.cs index 4ac3b0c221..81f9d14cdc 100644 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/LightPointShadowMapRendererCubeMap.cs +++ b/sources/engine/Stride.Rendering/Rendering/Shadows/LightPointShadowMapRendererCubeMap.cs @@ -53,9 +53,8 @@ public override ILightShadowMapShaderGroupData CreateShaderGroupData(LightShadow public override bool CanRenderLight(IDirectLight light) { - var lightPoint = light as LightPoint; - if (lightPoint != null) - return ((LightPointShadowMap)lightPoint.Shadow).Type == LightPointShadowMapType.CubeMap; + if (light is LightPoint lightPoint) + return lightPoint.Shadow.Type == LightPointShadowMapType.CubeMap; return false; } @@ -85,7 +84,7 @@ private static void GetViewParameters(LightShadowMapTexture shadowMapTexture, in /// private static Vector2 GetShadowMapDepthParameters(LightShadowMapTexture shadowMapTexture) { - var lightPoint = shadowMapTexture.Light as LightPoint; + var lightPoint = (LightPoint)shadowMapTexture.Light; Vector2 clippingPlanes = GetLightClippingPlanes(lightPoint); return CameraKeys.ZProjectionACalculate(clippingPlanes.X, clippingPlanes.Y); diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/LightPointShadowMapRendererParaboloid.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/LightPointShadowMapRendererParaboloid.cs index 859a58912e..64ced61c1e 100644 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/LightPointShadowMapRendererParaboloid.cs +++ b/sources/engine/Stride.Rendering/Rendering/Shadows/LightPointShadowMapRendererParaboloid.cs @@ -41,12 +41,8 @@ public override ILightShadowMapShaderGroupData CreateShaderGroupData(LightShadow public override bool CanRenderLight(IDirectLight light) { - var pl = light as LightPoint; - if (pl != null) - { - var type = ((LightPointShadowMap)pl.Shadow).Type; - return type == LightPointShadowMapType.DualParaboloid; - } + if (light is LightPoint lightPoint) + return lightPoint.Shadow.Type == LightPointShadowMapType.DualParaboloid; return false; } @@ -121,7 +117,7 @@ public override void Collect(RenderContext context, RenderView sourceView, Light /// private void CalculateViewDirection(LightShadowMapTexture shadowMapTexture) { - var pointShadowMapTexture = shadowMapTexture as ShadowMapTexture; + var pointShadowMapTexture = (ShadowMapTexture)shadowMapTexture; Matrix.Orthonormalize(ref shadowMapTexture.RenderLight.WorldMatrix, out pointShadowMapTexture.ForwardMatrix); pointShadowMapTexture.ForwardMatrix.Invert(); } @@ -134,7 +130,7 @@ private void CalculateViewDirection(LightShadowMapTexture shadowMapTexture) /// private Vector2 GetShadowMapDepthParameters(LightShadowMapTexture shadowMapTexture) { - var lightPoint = shadowMapTexture.Light as LightPoint; + var lightPoint = (LightPoint)shadowMapTexture.Light; Vector2 clippingPlanes = GetLightClippingPlanes(lightPoint); return new Vector2(clippingPlanes.X, 1.0f / (clippingPlanes.Y - clippingPlanes.X)); } @@ -146,12 +142,12 @@ private Vector2 GetLightClippingPlanes(LightPoint pointLight) private float GetShadowMapFarPlane(LightShadowMapTexture shadowMapTexture) { - return GetLightClippingPlanes(shadowMapTexture.Light as LightPoint).Y; + return GetLightClippingPlanes((LightPoint)shadowMapTexture.Light).Y; } private void GetViewParameters(LightShadowMapTexture shadowMapTexture, int index, out Matrix view, bool forCasting) { - var pointShadowMapTexture = shadowMapTexture as ShadowMapTexture; + var pointShadowMapTexture = (ShadowMapTexture)shadowMapTexture; Matrix flippingMatrix = Matrix.Identity; // Flip Y for rendering shadow maps