From 4b7d31f2b2a841d2514092afa4f8f7e38a132d45 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 8 Dec 2020 03:07:41 -0800 Subject: [PATCH] refactor directional shadow data --- DirectionalShadowMapData.cs | 9 ++-- Renderer.cs | 93 +++++++++++++++++++------------------ 2 files changed, 52 insertions(+), 50 deletions(-) diff --git a/DirectionalShadowMapData.cs b/DirectionalShadowMapData.cs index 4eca964..455d7d1 100644 --- a/DirectionalShadowMapData.cs +++ b/DirectionalShadowMapData.cs @@ -9,10 +9,8 @@ namespace Kav public RenderTarget2D[] ShadowMaps { get; } - public Matrix LightSpaceMatrixOne { get; set; } - public Matrix LightSpaceMatrixTwo { get; set; } - public Matrix LightSpaceMatrixThree { get; set; } - public Matrix LightSpaceMatrixFour { get; set; } + public Matrix[] LightSpaceViews { get; } + public Matrix[] LightSpaceProjections { get; } public float[] CascadeFarPlanes { get; } @@ -27,6 +25,9 @@ namespace Kav ShadowMapSize = shadowMapSize; NumShadowCascades = (int)MathHelper.Clamp(numCascades, 1, MAX_SHADOW_CASCADES); + LightSpaceViews = new Matrix[4]; + LightSpaceProjections = new Matrix[4]; + ShadowMaps = new RenderTarget2D[NumShadowCascades]; for (var i = 0; i < NumShadowCascades; i++) diff --git a/Renderer.cs b/Renderer.cs index a3cb74a..2cc799f 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -518,25 +518,25 @@ namespace Kav DeferredDirectionalLightEffect.ShadowMapSize = shadowMapData.ShadowMapSize; DeferredDirectionalLightEffect.ShadowMapOne = shadowMapData.ShadowMaps[0]; - DeferredDirectionalLightEffect.LightSpaceMatrixOne = shadowMapData.LightSpaceMatrixOne; + DeferredDirectionalLightEffect.LightSpaceMatrixOne = shadowMapData.LightSpaceViews[0] * shadowMapData.LightSpaceProjections[0]; DeferredDirectionalLightEffect.CascadeFarPlanes[0] = shadowMapData.CascadeFarPlanes[0]; if (shadowMapData.NumShadowCascades > 1) { DeferredDirectionalLightEffect.ShadowMapTwo = shadowMapData.ShadowMaps[1]; - DeferredDirectionalLightEffect.LightSpaceMatrixTwo = shadowMapData.LightSpaceMatrixTwo; + DeferredDirectionalLightEffect.LightSpaceMatrixTwo = shadowMapData.LightSpaceViews[1] * shadowMapData.LightSpaceProjections[1]; DeferredDirectionalLightEffect.CascadeFarPlanes[1] = shadowMapData.CascadeFarPlanes[1]; } if (shadowMapData.NumShadowCascades > 2) { DeferredDirectionalLightEffect.ShadowMapThree = shadowMapData.ShadowMaps[2]; - DeferredDirectionalLightEffect.LightSpaceMatrixThree = shadowMapData.LightSpaceMatrixThree; + DeferredDirectionalLightEffect.LightSpaceMatrixThree = shadowMapData.LightSpaceViews[2] * shadowMapData.LightSpaceProjections[2]; DeferredDirectionalLightEffect.CascadeFarPlanes[2] = shadowMapData.CascadeFarPlanes[2]; } if (shadowMapData.NumShadowCascades > 3) { DeferredDirectionalLightEffect.ShadowMapFour = shadowMapData.ShadowMaps[3]; - DeferredDirectionalLightEffect.LightSpaceMatrixFour = shadowMapData.LightSpaceMatrixFour; + DeferredDirectionalLightEffect.LightSpaceMatrixFour = shadowMapData.LightSpaceViews[3] * shadowMapData.LightSpaceProjections[3]; DeferredDirectionalLightEffect.CascadeFarPlanes[3] = shadowMapData.CascadeFarPlanes[3]; } @@ -579,22 +579,22 @@ namespace Kav directionalLight.Color.ToVector3() * directionalLight.Intensity; Deferred_ToonEffect.ShadowMapOne = shadowMapData.ShadowMaps[0]; - Deferred_ToonEffect.LightSpaceMatrixOne = shadowMapData.LightSpaceMatrixOne; + Deferred_ToonEffect.LightSpaceMatrixOne = shadowMapData.LightSpaceViews[0] * shadowMapData.LightSpaceProjections[0]; if (shadowMapData.NumShadowCascades > 1) { Deferred_ToonEffect.ShadowMapTwo = shadowMapData.ShadowMaps[1]; - Deferred_ToonEffect.LightSpaceMatrixTwo = shadowMapData.LightSpaceMatrixTwo; + Deferred_ToonEffect.LightSpaceMatrixTwo = shadowMapData.LightSpaceViews[1] * shadowMapData.LightSpaceProjections[1]; } if (shadowMapData.NumShadowCascades > 2) { Deferred_ToonEffect.ShadowMapThree = shadowMapData.ShadowMaps[2]; - Deferred_ToonEffect.LightSpaceMatrixThree = shadowMapData.LightSpaceMatrixThree; + Deferred_ToonEffect.LightSpaceMatrixThree = shadowMapData.LightSpaceViews[1] * shadowMapData.LightSpaceProjections[2]; } if (shadowMapData.NumShadowCascades > 3) { Deferred_ToonEffect.ShadowMapFour = shadowMapData.ShadowMaps[3]; - Deferred_ToonEffect.LightSpaceMatrixFour = shadowMapData.LightSpaceMatrixFour; + Deferred_ToonEffect.LightSpaceMatrixFour = shadowMapData.LightSpaceViews[2] * shadowMapData.LightSpaceProjections[3]; } Deferred_ToonEffect.ViewMatrix = camera.View; @@ -602,13 +602,11 @@ namespace Kav RenderFullscreenEffect(Deferred_ToonEffect); } - public void RenderDirectionalShadowsIndexed( + public void PrepareDirectionalShadowData( DirectionalShadowMapData shadowMapData, PerspectiveCamera camera, - IEnumerable<(T, Matrix)> drawableTransforms, DirectionalLight directionalLight - ) where T : ICullable, IIndexDrawable { - // render the individual shadow cascades + ) { var previousFarPlane = camera.NearPlane; for (var i = 0; i < shadowMapData.NumShadowCascades; i++) { @@ -625,11 +623,10 @@ namespace Kav farPlane ); - RenderDirectionalShadowMapIndexed( - shadowMapData, - i, - shadowCamera, - drawableTransforms, + PrepareDirectionalShadowCascade( + shadowMapData, + i, + shadowCamera, directionalLight ); @@ -638,18 +635,13 @@ namespace Kav } } - public void RenderDirectionalShadowMapIndexed( + private void PrepareDirectionalShadowCascade( DirectionalShadowMapData shadowMapData, int shadowCascadeIndex, - PerspectiveCamera camera, - IEnumerable<(T, Matrix)> drawableTransforms, + PerspectiveCamera shadowCamera, DirectionalLight directionalLight - ) where T : ICullable, IIndexDrawable { - GraphicsDevice.SetRenderTarget(shadowMapData.ShadowMaps[shadowCascadeIndex]); - GraphicsDevice.DepthStencilState = DepthStencilState.Default; - GraphicsDevice.BlendState = BlendState.Opaque; - - var cameraBoundingFrustum = new BoundingFrustum(camera.View * camera.Projection); + ) { + var cameraBoundingFrustum = new BoundingFrustum(shadowCamera.View * shadowCamera.Projection); Vector3[] frustumCorners = cameraBoundingFrustum.GetCorners(); Vector3 frustumCenter = Vector3.Zero; @@ -668,8 +660,8 @@ namespace Kav BoundingBox lightBox = BoundingBox.CreateFromPoints(frustumCorners); - SimpleDepthEffect.View = lightView; - SimpleDepthEffect.Projection = Matrix.CreateOrthographicOffCenter( + shadowMapData.LightSpaceViews[shadowCascadeIndex] = lightView; + shadowMapData.LightSpaceProjections[shadowCascadeIndex] = Matrix.CreateOrthographicOffCenter( lightBox.Min.X, lightBox.Max.X, lightBox.Min.Y, @@ -677,29 +669,38 @@ namespace Kav -lightBox.Max.Z - 10f, // TODO: near clip plane needs scene AABB info to get rid of this magic value -lightBox.Min.Z ); + } - var lightSpaceMatrix = SimpleDepthEffect.View * SimpleDepthEffect.Projection; + public void RenderDirectionalShadowsIndexed( + DirectionalShadowMapData shadowMapData, + IEnumerable<(T, Matrix)> drawableTransforms + ) where T : ICullable, IIndexDrawable { + // render the individual shadow cascades + for (var i = 0; i < shadowMapData.NumShadowCascades; i++) + { + RenderDirectionalShadowMapIndexed( + shadowMapData, + i, + drawableTransforms + ); + } + } - if (shadowCascadeIndex == 0) - { - shadowMapData.LightSpaceMatrixOne = lightSpaceMatrix; - } - else if (shadowCascadeIndex == 1) - { - shadowMapData.LightSpaceMatrixTwo = lightSpaceMatrix; - } - else if (shadowCascadeIndex == 2) - { - shadowMapData.LightSpaceMatrixThree = lightSpaceMatrix; - } - else if (shadowCascadeIndex == 3) - { - shadowMapData.LightSpaceMatrixFour = lightSpaceMatrix; - } + public void RenderDirectionalShadowMapIndexed( + DirectionalShadowMapData shadowMapData, + int shadowCascadeIndex, + IEnumerable<(T, Matrix)> drawableTransforms + ) where T : ICullable, IIndexDrawable { + GraphicsDevice.SetRenderTarget(shadowMapData.ShadowMaps[shadowCascadeIndex]); + GraphicsDevice.DepthStencilState = DepthStencilState.Default; + GraphicsDevice.BlendState = BlendState.Opaque; + + SimpleDepthEffect.View = shadowMapData.LightSpaceViews[shadowCascadeIndex]; + SimpleDepthEffect.Projection = shadowMapData.LightSpaceProjections[shadowCascadeIndex]; CullAndRenderIndexed( GraphicsDevice, - new BoundingFrustum(lightSpaceMatrix), + new BoundingFrustum(SimpleDepthEffect.View * SimpleDepthEffect.Projection), drawableTransforms, SimpleDepthEffect );