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 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++)

View File

@ -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<T>(
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<T>(
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<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)
{
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<T>(
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
);