I use this code to create the projections:

    Matrix CreateLightViewProjectionMatrix(LightProjectionDistance distance)
{
// Matrix with that will rotate in points the direction of the light
Matrix lightRotation = Matrix.CreateLookAt(Vector3.Zero,
-_lightDir,
Vector3.Up);

BoundingFrustum cameraFrustum = new BoundingFrustum(_view);
switch (distance)
{
case LightProjectionDistance.Close:
cameraFrustum = new BoundingFrustum(_view * _projectionClose);
break;
case LightProjectionDistance.Medium:
cameraFrustum = new BoundingFrustum(_view * _projectionMedium);
break;
case LightProjectionDistance.Far:
cameraFrustum = new BoundingFrustum(_view * _projectionFar);
break;
}

// Get the corners of the frustum
Vector3[] frustumCorners = cameraFrustum.GetCorners();

// Transform the positions of the corners into the direction of the light
for (int i = 0; i < frustumCorners.Length; i++)
{
frustumCorners[i] = Vector3.Transform(frustumCorners[i], lightRotation);
}

// Find the smallest box around the points
BoundingBox lightBox = BoundingBox.CreateFromPoints(frustumCorners);

Vector3 boxSize = lightBox.Max - lightBox.Min;
Vector3 halfBoxSize = boxSize * 0.5f;

// The position of the light should be in the center of the back
// pannel of the box.
Vector3 lightPosition = lightBox.Min + halfBoxSize;
lightPosition.Z = lightBox.Min.Z;

// We need the position back in world coordinates so we transform
// the light position by the inverse of the lights rotation
lightPosition = Vector3.Transform(lightPosition,
Matrix.Invert(lightRotation));

// Create the view matrix for the light
Matrix lightView = Matrix.CreateLookAt(lightPosition,
lightPosition - _lightDir,
Vector3.Up);

// Create the projection matrix for the light
// The projection is orthographic since we are using a directional light
Matrix lightProjection = Matrix.CreateOrthographic(boxSize.X, boxSize.Y,
-boxSize.Z, boxSize.Z);

return lightView * lightProjection;
}


Where the view matrices are like this:

        float aspectRatio = (float)graphics.PreferredBackBufferWidth / (float)graphics.PreferredBackBufferHeight;
_projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
aspectRatio,
1f, 500.0f);
_projectionClose = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
aspectRatio,
1f, 20.0f);
_projectionMedium = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
aspectRatio,
20.0f, 100.0f);
_projectionFar = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
aspectRatio,
100.0f, 500.0f);


In my Pixelshader I try this:

diffuse = input.Color;
float4 lightingPosition = mul(input.WorldPos, LightViewProjClose);
if (lightingPosition.x > -0.5 && lightingPosition.x<0.5 && lightingPosition.y>-0.5 && lightingPosition.y < 0.5)
{
diffuse = float4(1,0,0,1);
}

lightingPosition = mul(input.WorldPos, LightViewProjMedium);
if (lightingPosition.x > -0.5 && lightingPosition.x<0.5 && lightingPosition.y>-0.5 && lightingPosition.y < 0.5)
{
diffuse = float4(0,1,0,1);
}

lightingPosition = mul(input.WorldPos, LightViewProjFar);
if (lightingPosition.x > -0.5 && lightingPosition.x<0.5 && lightingPosition.y>-0.5 && lightingPosition.y < 0.5)
{
diffuse = float4(0,0,1,1);
}

return diffuse;


Now I expected to see the picture colored in red (close), green (medium) and blue (far) bands. However it seems only the close range is actually colored and the medium and far distances are not triggered. I did set the parameters like this:

_myEffect.Parameters["LightViewProjClose"].SetValue(CreateLightViewProjectionMatrix(LightProjectionDistance.Close));
_myEffect.Parameters["LightViewProjMedium"].SetValue(CreateLightViewProjectionMatrix(LightProjectionDistance.Medium));
_myEffect.Parameters["LightViewProjFar"].SetValue(CreateLightViewProjectionMatrix(LightProjectionDistance.Far));


I'm getting frustrated as I'm trying to figure this out for the past couple of days with almost no progress. What am I missing? How can I get the pixel shader switch between the correct light projections so it can pick the right cascaded shadowmap?

Edit, after tweaking this is my shader code:

float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 LightViewProjClose;
float4x4 LightViewProjMedium;
float4x4 LightViewProjFar;

float3 LightDirection1 = float3(-1.5, 0.45, 0);
float4 LightColor1 = float4(1, 1, 1, 1);
float3 LightDirection2 =float3(1,1,0.2);
float4 LightColor2 = float4(0.2, 0.2, 0.25, 1);

float4 AmbientColor = float4(0.15, 0.15, 0.15, 0.15);
float DepthBias = 0.001f;

{
};

{
float4 Position : SV_POSITION;
float4 Normal : NORMAL0;
float4 Color : COLOR0;
};

{
float4 Position : SV_POSITION;
float4 Normal : NORMAL0;
float4 Color : COLOR0;
};

{
float4 Position : SV_POSITION;
float4 Normal   : TEXCOORD0;
float4 Color    : COLOR0;
float4 WorldPos : TEXCOORD2;
};

{
float4 Position : POSITION;
float4 Color : COLOR0;
};

{

float4x4 WorldViewProj = mul(mul(World, View), Projection);

// Transform the models verticies and normal
output.Position = mul(input.Position, WorldViewProj);
output.Normal =  input.Normal;
output.Color = input.Color;

// Save the vertices postion in world space
output.WorldPos = mul(input.Position, World);

return output;
}

{
// Color of the model
float4 diffuseColor = input.Color;

// Intensity based on the direction of the light
float diffuseIntensity1 = clamp(dot(input.Normal.xyz, LightDirection1.xyz), 0, 1);
float diffuseIntensity2 = clamp(dot(input.Normal.xyz, LightDirection2.xyz), 0, 1);

// Final diffuse color with ambient color added
float4 diffuse = saturate((diffuseIntensity1 * LightColor1 + diffuseIntensity2 * LightColor2) * diffuseColor);

// Find the position of this pixel in light space in the close projection
float4 lightingPosition = mul(input.WorldPos, LightViewProjClose);
lightingPosition.xyz = 0.5 * lightingPosition.xyz / lightingPosition.w;
if (lightingPosition.x > -0.5 && lightingPosition.x<0.5 && lightingPosition.y>-0.5 && lightingPosition.y < 0.5)
{
lightingPosition = mul(input.WorldPos, LightViewProjClose);
// Find the position in the shadow map for this pixel
float2 ShadowTexCoord = 0.5 * lightingPosition.xy /
lightingPosition.w + float2(0.5, 0.5);

// Get the current depth stored in the shadow map (red component for close)

// Calculate the current pixel depth
// The bias is used to prevent floating point errors that occur when
// the pixel of the occluder is being drawn
float ourdepth = (lightingPosition.z / lightingPosition.w) - DepthBias;

// Check to see if this pixel is in front or behind the value in the shadow map
{
// Shadow the pixel by lowering the intensity
diffuse *= float4(0.5, 0.5, 0.5, 0);

};
}

lightingPosition = mul(input.WorldPos, LightViewProjMedium);
lightingPosition.xyz = 0.5 * lightingPosition.xyz / lightingPosition.w;
if (lightingPosition.x > -0.5 && lightingPosition.x<0.5 && lightingPosition.y>-0.5 && lightingPosition.y < 0.5)
{

lightingPosition = mul(input.WorldPos, LightViewProjMedium);
// Find the position in the shadow map for this pixel
float2 ShadowTexCoord = 0.5 * lightingPosition.xy /
lightingPosition.w + float2(0.5, 0.5);

// Get the current depth stored in the shadow map (green component for medium)

// Calculate the current pixel depth
// The bias is used to prevent floating point errors that occur when
// the pixel of the occluder is being drawn
float ourdepth = (lightingPosition.z / lightingPosition.w) - DepthBias;

// Check to see if this pixel is in front or behind the value in the shadow map
{
// Shadow the pixel by lowering the intensity
diffuse *= float4(0.5, 0.5, 0.5, 0);
};
}

//do the same trick using the 'far' matrix.
lightingPosition = mul(input.WorldPos, LightViewProjFar);
lightingPosition.xyz = 0.5 * lightingPosition.xyz / lightingPosition.w;
if (lightingPosition.x > -0.5 && lightingPosition.x<0.5 && lightingPosition.y>-0.5 && lightingPosition.y < 0.5)
{
lightingPosition = mul(input.WorldPos, LightViewProjFar);

// Find the position in the shadow map for this pixel
float2 ShadowTexCoord = 0.5 * lightingPosition.xy /
lightingPosition.w + float2(0.5, 0.5);

// Get the current depth stored in the shadow map (blue component for far)

// Calculate the current pixel depth
// The bias is used to prevent floating point errors that occur when
// the pixel of the occluder is being drawn
float ourdepth = (lightingPosition.z / lightingPosition.w) - DepthBias;

// Check to see if this pixel is in front or behind the value in the shadow map
{
// Shadow the pixel by lowering the intensity
diffuse *= float4(0.5, 0.5, 0.5, 0);
};
//diffuse = float4(0, 0, 1, 1);
}
return diffuse;
}

{

output.Position = mul(input.Position, mul(World, LightViewProjClose));
output.Color = float4(output.Position.z / output.Position.w,0,0,1);

return output;
}
{

output.Position = mul(input.Position, mul(World, LightViewProjMedium));
output.Color = float4(0,output.Position.z / output.Position.w, 0, 1);

return output;
}
{

output.Position = mul(input.Position, mul(World, LightViewProjFar));
output.Color = float4(0,0,output.Position.z / output.Position.w, 1);

return output;
}

{
return input.Color;
}

technique MyTechnique
{
pass Pass1
{
}
}

{

pass Pass1
{
}
}
{

pass Pass1
{
}
}
{

pass Pass1
{
}
}


The "close" shadows seem to work. However the 'medium' and 'far' shadows are still not working. The result looks like this:

What am I doing wrong here?

• Well, once you divided by the w component after 'mul' -ing with the matrix, you don't need to divide anymore for that value. Now you do it for the texcoords which is unnecessary. Dec 25, 2015 at 21:54
• Ah, yes thanks for that. I did that optimization (I guess there is plenty of optimization possible). Dec 26, 2015 at 11:47

So after float4 lightingPosition = mul(input.WorldPos, LightViewProjClose); but before the if you should do this:
lightingPosition.xyz /= lightingPosition.w