refactor directional shadow data

instancing
cosmonaut 2020-12-08 03:07:41 -08:00
parent 4d3c5fc316
commit 4b7d31f2b2
2 changed files with 52 additions and 50 deletions

View File

@ -9,10 +9,8 @@ namespace Kav
public RenderTarget2D[] ShadowMaps { get; } public RenderTarget2D[] ShadowMaps { get; }
public Matrix LightSpaceMatrixOne { get; set; } public Matrix[] LightSpaceViews { get; }
public Matrix LightSpaceMatrixTwo { get; set; } public Matrix[] LightSpaceProjections { get; }
public Matrix LightSpaceMatrixThree { get; set; }
public Matrix LightSpaceMatrixFour { get; set; }
public float[] CascadeFarPlanes { get; } public float[] CascadeFarPlanes { get; }
@ -27,6 +25,9 @@ namespace Kav
ShadowMapSize = shadowMapSize; ShadowMapSize = shadowMapSize;
NumShadowCascades = (int)MathHelper.Clamp(numCascades, 1, MAX_SHADOW_CASCADES); NumShadowCascades = (int)MathHelper.Clamp(numCascades, 1, MAX_SHADOW_CASCADES);
LightSpaceViews = new Matrix[4];
LightSpaceProjections = new Matrix[4];
ShadowMaps = new RenderTarget2D[NumShadowCascades]; ShadowMaps = new RenderTarget2D[NumShadowCascades];
for (var i = 0; i < NumShadowCascades; i++) for (var i = 0; i < NumShadowCascades; i++)

View File

@ -518,25 +518,25 @@ namespace Kav
DeferredDirectionalLightEffect.ShadowMapSize = shadowMapData.ShadowMapSize; DeferredDirectionalLightEffect.ShadowMapSize = shadowMapData.ShadowMapSize;
DeferredDirectionalLightEffect.ShadowMapOne = shadowMapData.ShadowMaps[0]; DeferredDirectionalLightEffect.ShadowMapOne = shadowMapData.ShadowMaps[0];
DeferredDirectionalLightEffect.LightSpaceMatrixOne = shadowMapData.LightSpaceMatrixOne; DeferredDirectionalLightEffect.LightSpaceMatrixOne = shadowMapData.LightSpaceViews[0] * shadowMapData.LightSpaceProjections[0];
DeferredDirectionalLightEffect.CascadeFarPlanes[0] = shadowMapData.CascadeFarPlanes[0]; DeferredDirectionalLightEffect.CascadeFarPlanes[0] = shadowMapData.CascadeFarPlanes[0];
if (shadowMapData.NumShadowCascades > 1) if (shadowMapData.NumShadowCascades > 1)
{ {
DeferredDirectionalLightEffect.ShadowMapTwo = shadowMapData.ShadowMaps[1]; DeferredDirectionalLightEffect.ShadowMapTwo = shadowMapData.ShadowMaps[1];
DeferredDirectionalLightEffect.LightSpaceMatrixTwo = shadowMapData.LightSpaceMatrixTwo; DeferredDirectionalLightEffect.LightSpaceMatrixTwo = shadowMapData.LightSpaceViews[1] * shadowMapData.LightSpaceProjections[1];
DeferredDirectionalLightEffect.CascadeFarPlanes[1] = shadowMapData.CascadeFarPlanes[1]; DeferredDirectionalLightEffect.CascadeFarPlanes[1] = shadowMapData.CascadeFarPlanes[1];
} }
if (shadowMapData.NumShadowCascades > 2) if (shadowMapData.NumShadowCascades > 2)
{ {
DeferredDirectionalLightEffect.ShadowMapThree = shadowMapData.ShadowMaps[2]; DeferredDirectionalLightEffect.ShadowMapThree = shadowMapData.ShadowMaps[2];
DeferredDirectionalLightEffect.LightSpaceMatrixThree = shadowMapData.LightSpaceMatrixThree; DeferredDirectionalLightEffect.LightSpaceMatrixThree = shadowMapData.LightSpaceViews[2] * shadowMapData.LightSpaceProjections[2];
DeferredDirectionalLightEffect.CascadeFarPlanes[2] = shadowMapData.CascadeFarPlanes[2]; DeferredDirectionalLightEffect.CascadeFarPlanes[2] = shadowMapData.CascadeFarPlanes[2];
} }
if (shadowMapData.NumShadowCascades > 3) if (shadowMapData.NumShadowCascades > 3)
{ {
DeferredDirectionalLightEffect.ShadowMapFour = shadowMapData.ShadowMaps[3]; DeferredDirectionalLightEffect.ShadowMapFour = shadowMapData.ShadowMaps[3];
DeferredDirectionalLightEffect.LightSpaceMatrixFour = shadowMapData.LightSpaceMatrixFour; DeferredDirectionalLightEffect.LightSpaceMatrixFour = shadowMapData.LightSpaceViews[3] * shadowMapData.LightSpaceProjections[3];
DeferredDirectionalLightEffect.CascadeFarPlanes[3] = shadowMapData.CascadeFarPlanes[3]; DeferredDirectionalLightEffect.CascadeFarPlanes[3] = shadowMapData.CascadeFarPlanes[3];
} }
@ -579,22 +579,22 @@ namespace Kav
directionalLight.Color.ToVector3() * directionalLight.Intensity; directionalLight.Color.ToVector3() * directionalLight.Intensity;
Deferred_ToonEffect.ShadowMapOne = shadowMapData.ShadowMaps[0]; Deferred_ToonEffect.ShadowMapOne = shadowMapData.ShadowMaps[0];
Deferred_ToonEffect.LightSpaceMatrixOne = shadowMapData.LightSpaceMatrixOne; Deferred_ToonEffect.LightSpaceMatrixOne = shadowMapData.LightSpaceViews[0] * shadowMapData.LightSpaceProjections[0];
if (shadowMapData.NumShadowCascades > 1) if (shadowMapData.NumShadowCascades > 1)
{ {
Deferred_ToonEffect.ShadowMapTwo = shadowMapData.ShadowMaps[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) if (shadowMapData.NumShadowCascades > 2)
{ {
Deferred_ToonEffect.ShadowMapThree = shadowMapData.ShadowMaps[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) if (shadowMapData.NumShadowCascades > 3)
{ {
Deferred_ToonEffect.ShadowMapFour = shadowMapData.ShadowMaps[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; Deferred_ToonEffect.ViewMatrix = camera.View;
@ -602,13 +602,11 @@ namespace Kav
RenderFullscreenEffect(Deferred_ToonEffect); RenderFullscreenEffect(Deferred_ToonEffect);
} }
public void RenderDirectionalShadowsIndexed<T>( public void PrepareDirectionalShadowData(
DirectionalShadowMapData shadowMapData, DirectionalShadowMapData shadowMapData,
PerspectiveCamera camera, PerspectiveCamera camera,
IEnumerable<(T, Matrix)> drawableTransforms,
DirectionalLight directionalLight DirectionalLight directionalLight
) where T : ICullable, IIndexDrawable { ) {
// render the individual shadow cascades
var previousFarPlane = camera.NearPlane; var previousFarPlane = camera.NearPlane;
for (var i = 0; i < shadowMapData.NumShadowCascades; i++) for (var i = 0; i < shadowMapData.NumShadowCascades; i++)
{ {
@ -625,11 +623,10 @@ namespace Kav
farPlane farPlane
); );
RenderDirectionalShadowMapIndexed( PrepareDirectionalShadowCascade(
shadowMapData, shadowMapData,
i, i,
shadowCamera, shadowCamera,
drawableTransforms,
directionalLight directionalLight
); );
@ -638,18 +635,13 @@ namespace Kav
} }
} }
public void RenderDirectionalShadowMapIndexed<T>( private void PrepareDirectionalShadowCascade(
DirectionalShadowMapData shadowMapData, DirectionalShadowMapData shadowMapData,
int shadowCascadeIndex, int shadowCascadeIndex,
PerspectiveCamera camera, PerspectiveCamera shadowCamera,
IEnumerable<(T, Matrix)> drawableTransforms,
DirectionalLight directionalLight DirectionalLight directionalLight
) where T : ICullable, IIndexDrawable { ) {
GraphicsDevice.SetRenderTarget(shadowMapData.ShadowMaps[shadowCascadeIndex]); var cameraBoundingFrustum = new BoundingFrustum(shadowCamera.View * shadowCamera.Projection);
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.BlendState = BlendState.Opaque;
var cameraBoundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
Vector3[] frustumCorners = cameraBoundingFrustum.GetCorners(); Vector3[] frustumCorners = cameraBoundingFrustum.GetCorners();
Vector3 frustumCenter = Vector3.Zero; Vector3 frustumCenter = Vector3.Zero;
@ -668,8 +660,8 @@ namespace Kav
BoundingBox lightBox = BoundingBox.CreateFromPoints(frustumCorners); BoundingBox lightBox = BoundingBox.CreateFromPoints(frustumCorners);
SimpleDepthEffect.View = lightView; shadowMapData.LightSpaceViews[shadowCascadeIndex] = lightView;
SimpleDepthEffect.Projection = Matrix.CreateOrthographicOffCenter( shadowMapData.LightSpaceProjections[shadowCascadeIndex] = Matrix.CreateOrthographicOffCenter(
lightBox.Min.X, lightBox.Min.X,
lightBox.Max.X, lightBox.Max.X,
lightBox.Min.Y, 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.Max.Z - 10f, // TODO: near clip plane needs scene AABB info to get rid of this magic value
-lightBox.Min.Z -lightBox.Min.Z
); );
}
var lightSpaceMatrix = SimpleDepthEffect.View * SimpleDepthEffect.Projection; public void RenderDirectionalShadowsIndexed<T>(
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) public void RenderDirectionalShadowMapIndexed<T>(
{ DirectionalShadowMapData shadowMapData,
shadowMapData.LightSpaceMatrixOne = lightSpaceMatrix; int shadowCascadeIndex,
} IEnumerable<(T, Matrix)> drawableTransforms
else if (shadowCascadeIndex == 1) ) where T : ICullable, IIndexDrawable {
{ GraphicsDevice.SetRenderTarget(shadowMapData.ShadowMaps[shadowCascadeIndex]);
shadowMapData.LightSpaceMatrixTwo = lightSpaceMatrix; GraphicsDevice.DepthStencilState = DepthStencilState.Default;
} GraphicsDevice.BlendState = BlendState.Opaque;
else if (shadowCascadeIndex == 2)
{ SimpleDepthEffect.View = shadowMapData.LightSpaceViews[shadowCascadeIndex];
shadowMapData.LightSpaceMatrixThree = lightSpaceMatrix; SimpleDepthEffect.Projection = shadowMapData.LightSpaceProjections[shadowCascadeIndex];
}
else if (shadowCascadeIndex == 3)
{
shadowMapData.LightSpaceMatrixFour = lightSpaceMatrix;
}
CullAndRenderIndexed( CullAndRenderIndexed(
GraphicsDevice, GraphicsDevice,
new BoundingFrustum(lightSpaceMatrix), new BoundingFrustum(SimpleDepthEffect.View * SimpleDepthEffect.Projection),
drawableTransforms, drawableTransforms,
SimpleDepthEffect SimpleDepthEffect
); );