fixing CSM gaps
parent
a55e33f9a9
commit
314b308840
|
@ -46,7 +46,7 @@ namespace Kav
|
|||
public Matrix LightSpaceMatrixFour { get; set; }
|
||||
|
||||
public Matrix ViewMatrix { get; set; }
|
||||
public float[] CascadeFarPlanes;
|
||||
public readonly float[] CascadeFarPlanes;
|
||||
|
||||
public Vector3 DirectionalLightColor { get; set; }
|
||||
public Vector3 DirectionalLightDirection { get; set; }
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -111,7 +111,7 @@ float ComputeShadow(float3 positionWorldSpace, float3 N, float L)
|
|||
int shadowCascadeIndex = 0; // 0 is closest
|
||||
for (int i = 0; i < NUM_SHADOW_CASCADES; i++)
|
||||
{
|
||||
if (positionCameraSpace.z < CascadeFarPlanes[i])
|
||||
if (abs(positionCameraSpace.z) < CascadeFarPlanes[i])
|
||||
{
|
||||
shadowCascadeIndex = i;
|
||||
break;
|
||||
|
@ -146,35 +146,61 @@ float ComputeShadow(float3 positionWorldSpace, float3 N, float L)
|
|||
projectionCoords.x = (projectionCoords.x * 0.5) + 0.5;
|
||||
projectionCoords.y = (projectionCoords.y * 0.5) + 0.5;
|
||||
projectionCoords.y *= -1;
|
||||
// in XNA clip z is 0 to 1 already
|
||||
|
||||
float inc = 1.0 / 1024.0;
|
||||
|
||||
float shadowFactor = 0;
|
||||
for (int row = -1; row <= 1; row++)
|
||||
{
|
||||
for (int col = -1; col <= 1; col++)
|
||||
{
|
||||
float closestDepth;
|
||||
if (shadowCascadeIndex == 0)
|
||||
{
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapOne, projectionCoords.xy).r;
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapOne, projectionCoords.xy + float2(row, col) * inc).r;
|
||||
}
|
||||
else if (shadowCascadeIndex == 1)
|
||||
{
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapTwo, projectionCoords.xy).r;
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapTwo, projectionCoords.xy + float2(row, col) * inc).r;
|
||||
}
|
||||
else if (shadowCascadeIndex == 2)
|
||||
{
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapThree, projectionCoords.xy).r;
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapThree, projectionCoords.xy + float2(row, col) * inc).r;
|
||||
}
|
||||
else
|
||||
{
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapFour, projectionCoords.xy).r;
|
||||
closestDepth = SAMPLE_TEXTURE(shadowMapFour, projectionCoords.xy + float2(row, col) * inc).r;
|
||||
}
|
||||
shadowFactor += projectionCoords.z - bias > closestDepth ? 1.0 : 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
float currentDepth = projectionCoords.z;
|
||||
shadowFactor /= 9.0;
|
||||
|
||||
if (currentDepth - bias > closestDepth)
|
||||
if (projectionCoords.z > 1.0)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0;
|
||||
shadowFactor = 1.0;
|
||||
}
|
||||
|
||||
return shadowFactor;
|
||||
|
||||
|
||||
// float currentDepth = projectionCoords.z;
|
||||
|
||||
// if (currentDepth > 1.0)
|
||||
// {
|
||||
// return 0.0;
|
||||
// }
|
||||
|
||||
// if (currentDepth - bias > closestDepth)
|
||||
// {
|
||||
// return 1.0;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return 0.0;
|
||||
// }
|
||||
}
|
||||
|
||||
float3 ComputeLight(
|
||||
|
@ -239,7 +265,6 @@ float4 ComputeColor(
|
|||
float3 radiance = DirectionalLightColor;
|
||||
|
||||
float shadow = ComputeShadow(worldPosition, N, L);
|
||||
|
||||
Lo += ComputeLight(L, radiance, F0, V, N, albedo, metallic, roughness, (1.0 - shadow));
|
||||
|
||||
float3 ambient = float3(0.03, 0.03, 0.03) * albedo; // * AO;
|
||||
|
|
|
@ -24,7 +24,7 @@ VertexShaderOutput main_vs(VertexShaderInput input)
|
|||
VertexShaderOutput output;
|
||||
|
||||
output.Position = mul(input.Position, ModelViewProjection);
|
||||
output.Depth = output.Position.z / output.Position.w;
|
||||
output.Depth = output.Position.z;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
24
Renderer.cs
24
Renderer.cs
|
@ -8,6 +8,7 @@ namespace Kav
|
|||
{
|
||||
private const int MAX_SHADOW_CASCADES = 4;
|
||||
|
||||
|
||||
private GraphicsDevice GraphicsDevice { get; }
|
||||
private int RenderDimensionsX { get; }
|
||||
private int RenderDimensionsY { get; }
|
||||
|
@ -235,11 +236,11 @@ namespace Kav
|
|||
|
||||
// render the individual shadow maps
|
||||
|
||||
var frustumDistance = camera.FarPlane - camera.NearPlane;
|
||||
var sectionDistance = frustumDistance / NumShadowCascades;
|
||||
|
||||
var previousFarPlane = camera.NearPlane;
|
||||
for (var i = 0; i < NumShadowCascades; i++)
|
||||
{
|
||||
var farPlane = camera.FarPlane / (MathHelper.Max((NumShadowCascades - i - 1) * 5f, 1f));
|
||||
|
||||
// divide the view frustum
|
||||
var shadowCamera = new PerspectiveCamera(
|
||||
camera.Position,
|
||||
|
@ -247,11 +248,13 @@ namespace Kav
|
|||
camera.Up,
|
||||
camera.FieldOfView,
|
||||
camera.AspectRatio,
|
||||
camera.NearPlane + (i * sectionDistance),
|
||||
camera.NearPlane + ((i + 1) * sectionDistance)
|
||||
previousFarPlane,
|
||||
farPlane
|
||||
);
|
||||
|
||||
RenderShadowMap(shadowCamera, modelTransforms, directionalLight, i);
|
||||
|
||||
previousFarPlane = farPlane;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,8 +269,6 @@ namespace Kav
|
|||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||
GraphicsDevice.BlendState = BlendState.Opaque;
|
||||
|
||||
var right = Vector3.Cross(Vector3.Up, directionalLight.Direction);
|
||||
var up = Vector3.Cross(directionalLight.Direction, right);
|
||||
var cameraBoundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
||||
Vector3[] frustumCorners = cameraBoundingFrustum.GetCorners();
|
||||
|
||||
|
@ -278,7 +279,7 @@ namespace Kav
|
|||
}
|
||||
frustumCenter /= 8f;
|
||||
|
||||
var lightView = Matrix.CreateLookAt(frustumCenter, frustumCenter - directionalLight.Direction, camera.View.Right);
|
||||
var lightView = Matrix.CreateLookAt(frustumCenter + directionalLight.Direction, frustumCenter, Vector3.Backward);
|
||||
|
||||
for (var i = 0; i < frustumCorners.Length; i++)
|
||||
{
|
||||
|
@ -286,16 +287,15 @@ namespace Kav
|
|||
}
|
||||
|
||||
BoundingBox lightBox = BoundingBox.CreateFromPoints(frustumCorners);
|
||||
Vector3 lightPosition = frustumCenter + directionalLight.Direction * -lightBox.Min.Z;
|
||||
|
||||
SimpleDepthEffect.View = Matrix.CreateLookAt(lightPosition, frustumCenter, camera.View.Right);
|
||||
SimpleDepthEffect.View = lightView;
|
||||
SimpleDepthEffect.Projection = Matrix.CreateOrthographicOffCenter(
|
||||
lightBox.Min.X,
|
||||
lightBox.Max.X,
|
||||
lightBox.Min.Y,
|
||||
lightBox.Max.Y,
|
||||
0,
|
||||
lightBox.Max.Z - lightBox.Min.Z
|
||||
-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;
|
||||
|
|
Loading…
Reference in New Issue