Sampling a cascaded shadow map

Started by
2 comments, last by MJP 13 years, 1 month ago
I have a 5120*1024 cascaded shadow map, so each cascade is 1024*1024 and I'm using 5 cascades.

I calculate each pixel view space position so I can choose which cascade do i have to use.

My question is: How do I sample the shadow map atlas in the correct position?
Advertisement

I have a 5120*1024 cascaded shadow map, so each cascade is 1024*1024 and I'm using 5 cascades.

I calculate each pixel view space position so I can choose which cascade do i have to use.

My question is: How do I sample the shadow map atlas in the correct position?


You just scale and offset the texture coordinate you get after projecting the pixel position by that cascade's shadow matrix:

float4x4 shadowMatrix = ShadowMatrices[cascadeIndex];
float4 shadowPosition = mul(float4(pixelPosition, 1.0f), shadowMatrix);

// Compute the texture coordinate by doing homogeneous divide + scale/offset
float2 shadowTexCoord = shadowPosition.xy / shadowPosition.w;
shadowTexCoord = shadowTexCoord * float2(0.5f, -0.5f) + float2(0.5f, 0.5f);

// Scale based on the number of cascades
float2 cascadeScale = float2(1.0f / NumCascades, 1.0f);
shadowTexCoord *= cascadeScale;

// Offset based on the cascade index
float2 cascadeOffset = float2(cascadeIndex / NumCascades, 0.0f);
shadowTexCoord += cascadeOffset;


You can also roll all of those calculations into your shadow matrices on the CPU, so that all you have to do is the shadow matrix transform + divide by w on the GPU.

[quote name='TiagoCosta' timestamp='1299367117' post='4782243']
I have a 5120*1024 cascaded shadow map, so each cascade is 1024*1024 and I'm using 5 cascades.

I calculate each pixel view space position so I can choose which cascade do i have to use.

My question is: How do I sample the shadow map atlas in the correct position?


You just scale and offset the texture coordinate you get after projecting the pixel position by that cascade's shadow matrix:

float4x4 shadowMatrix = ShadowMatrices[cascadeIndex];
float4 shadowPosition = mul(float4(pixelPosition, 1.0f), shadowMatrix);

// Compute the texture coordinate by doing homogeneous divide + scale/offset
float2 shadowTexCoord = shadowPosition.xy / shadowPosition.z;
shadowTexCoord = shadowTexCoord * float2(0.5f, -0.5f) + float2(0.5f, 0.5f);

// Scale based on the number of cascades
float2 cascadeScale = float2(1.0f / NumCascades, 1.0f);
shadowTexCoord *= cascadeScale;

// Offset based on the cascade index
float2 cascadeOffset = float2(cascadeIndex / NumCascades, 0.0f);
shadowTexCoord += cascadeOffset;


You can also roll all of those calculations into your shadow matrices on the CPU, so that all you have to do is the shadow matrix transform + divide by w on the GPU.
[/quote]

Thank you, but shouldnt it be:


//Divide by the w component
float2 shadowTexCoord = shadowPosition.xy / shadowPosition.w;

[quote name='MJP' timestamp='1299443937' post='4782528']
[quote name='TiagoCosta' timestamp='1299367117' post='4782243']
I have a 5120*1024 cascaded shadow map, so each cascade is 1024*1024 and I'm using 5 cascades.

I calculate each pixel view space position so I can choose which cascade do i have to use.

My question is: How do I sample the shadow map atlas in the correct position?


You just scale and offset the texture coordinate you get after projecting the pixel position by that cascade's shadow matrix:

float4x4 shadowMatrix = ShadowMatrices[cascadeIndex];
float4 shadowPosition = mul(float4(pixelPosition, 1.0f), shadowMatrix);

// Compute the texture coordinate by doing homogeneous divide + scale/offset
float2 shadowTexCoord = shadowPosition.xy / shadowPosition.z;
shadowTexCoord = shadowTexCoord * float2(0.5f, -0.5f) + float2(0.5f, 0.5f);

// Scale based on the number of cascades
float2 cascadeScale = float2(1.0f / NumCascades, 1.0f);
shadowTexCoord *= cascadeScale;

// Offset based on the cascade index
float2 cascadeOffset = float2(cascadeIndex / NumCascades, 0.0f);
shadowTexCoord += cascadeOffset;


You can also roll all of those calculations into your shadow matrices on the CPU, so that all you have to do is the shadow matrix transform + divide by w on the GPU.
[/quote]

Thank you, but shouldnt it be:


//Divide by the w component
float2 shadowTexCoord = shadowPosition.xy / shadowPosition.w;

[/quote]

Yup, that's a typo. Sorry about that.

This topic is closed to new replies.

Advertisement