Jump to content
  • Advertisement
Sign in to follow this  
bjarnia

Shadow maps being cut off

This topic is 3084 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to get my cascaded shadow maps implementation working and I'm facing a problem that I'm stuck on. This is the intended shadow for the car: http://www.steik.org/dump/Cosmopolis2010-04-1100-20-55-11.png This is however what I will see with a slightly different item-to-split population: http://www.steik.org/dump/Cosmopolis2010-04-1100-21-28-51.png During my debugging I came up with a dirty hack in the PCF function to at least make the wrong areas not black (shadowed) (see the first if statement)
    if (vTexCoord.z >= 0.999) 
    {
        ret = 1;
    }
    else
    {
        // 2x2 PCF Filtering    
        float fShadow[4];
        fShadow[0] = (vTexCoord.z - DepthBias[split] < tex2D(sam, vTexCoord + float2(0,         0)).r);
        fShadow[1] = (vTexCoord.z - DepthBias[split] < tex2D(sam, vTexCoord + float2(TexelSize, 0)).r);
        fShadow[2] = (vTexCoord.z - DepthBias[split] < tex2D(sam, vTexCoord + float2(0,         TexelSize)).r);
        fShadow[3] = (vTexCoord.z - DepthBias[split] < tex2D(sam, vTexCoord + float2(TexelSize, TexelSize)).r);
        
        float2 vLerpFactor = frac(ShadowMapSize * vTexCoord.xy);
        ret = lerp(lerp(fShadow[0], fShadow[1], vLerpFactor.x), lerp(fShadow[2], fShadow[3], vLerpFactor.x), vLerpFactor.y);
    }    
This is what happens with the hack: http://www.steik.org/dump/Cosmopolis2010-04-1100-20-51-76.png As you can see this is also a problem with the first split in all pictures. In all cases the geometry IS clearly being written in the depth map (see frames 1 and 2 on the top from the left), so I think it is just some stupid texture coordinate problem. I however have no idea pretty much why or how to fix this. I am basing my code on "Chapter 10: Parallel-Split Shadow Maps on Programmable GPUs" from GPU Gems 3. Clearly the LightViewProjection is correct since the depth maps are being drawn correctly, and the only thing I do extra when I sample it later is this: LightViewProjectionCropped * shadowMapTextureScale where the scaling matrix is a relatively standard matrix:
            
float shadowMapTexOffset = 0.5f + (0.5f / (float)shadowMapSize);

            return new Matrix(0.5f, 0.0f, 0.0f, 0.0f,
                              0.0f, -0.5f, 0.0f, 0.0f,
                              0.0f, 0.0f, 1.0f, 0.0f,
                              shadowMapTexOffset, shadowMapTexOffset, 0.0f, 1.0f);
      
So yeah.. This error doesn't really make sense to me since the depth maps are being drawn right. Any ideas?

Share this post


Link to post
Share on other sites
Advertisement
Hey, nice Lada 1200 model!

My guess is that you only apply the first (closest-to-light) shadowmap to the scene.
(BTW how did you get the working version?)

You have to sample from the other maps too.
I'm not in the shader stuff yet, and I don't know how the PSM works in that case, but I have a hunch that you should do something like this:
texture_unit = floor(vTexCoord.z); // will be 2 if vTexCoord.z = 2.3
vTexCoord.z -= texture_unit; // will be 0.3 if vTexCoord.z = 2.3

....
//take sample from texture_unit
But it's just a wild guess.

Share this post


Link to post
Share on other sites
Quote:
Original post by szecs
Hey, nice Lada 1200 model!

My guess is that you only apply the first (closest-to-light) shadowmap to the scene.
(BTW how did you get the working version?)

You have to sample from the other maps too.
I'm not in the shader stuff yet, and I don't know how the CSM works in that case, but I have a hunch that you should do something like this:
texture_unit = floor(vTexCoord.z); // will be 2 if vTexCoord.z = 2.3
vTexCoord.z -= texture_unit; // will be 0.3 if vTexCoord.z = 2.3

....
//take sample from texture_unit
But it's just a wild guess.


Working version of the GPU Gems Code? I can email it to you if you want.

I'm sampling from all of the maps, based on the coloring you see in the screenshot, thought that was kind of a given :) Red is closest, then green, blue and magenta.
That part works.

Edit: Also, that explanation would not fit since the part that is casting shadow is actually rendered on all of the depth maps.

Share this post


Link to post
Share on other sites
Then why don't I see it in the code?

Your code doesn't switch between textures, or you haven't posted the relevant code.

And the scene is just confusing. you should use simpler meshes for testing, cubes, for example. But the generated shadow maps seem fine.

I don't know, I guess I miss something, sorry.


BTW, your returned matrix seems very strange.
You only have to apply the offset (bias) in the 'z' direction:

(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, shadowMapTexOffset, 1.0f); //or maybe -shadowMapTexOffset

Or I totally misunderstand something.

Share this post


Link to post
Share on other sites
I'm confused by your shadow maps, are you sure they're not inverted? Assuming your sun position is supposed to be behind your viewer's right shoulder, shouldn't the 1st shadowmap have the front of the car on the left of the image rather than the right?

Edit: plus I totally agree with szecs that getting shadow mapping working with simple geometry is far easier. I'd stick a few different sized cubes in instead of the lada and try again.

Share this post


Link to post
Share on other sites
Quote:
Original post by szecs
Then why don't I see it in the code?

Your code doesn't switch between textures, or you haven't posted the relevant code.

And the scene is just confusing. you should use simpler meshes for testing, cubes, for example. But the generated shadow maps seem fine.

I don't know, I guess I miss something, sorry.


I refrained from posting the entire code as that that would likely be in the range of some hundred lines and resulting in a big wall of text.

The code I posted is just my SamplePCF function:
float SamplePCF(sampler2D sam, float4 vTexCoord, int split)

It is called as follows in the pixel shader:


if(fDistance < SplitDistances[0])
{
fLightingFactor = SamplePCF(ShadowMapSampler[0], input.vTexCoord[0], 0);
output.Color = float4(1, 0, 0, 1);
}
else if(fDistance < SplitDistances[1])
{
fLightingFactor = SamplePCF(ShadowMapSampler[1], input.vTexCoord[1], 1);
output.Color = float4(0, 1, 0, 1);
}
else if(fDistance < SplitDistances[2])
{
fLightingFactor = SamplePCF(ShadowMapSampler[2], input.vTexCoord[2], 2);
output.Color = float4(0, 0, 1, 1);
}
else if(fDistance < SplitDistances[3])
{
fLightingFactor = SamplePCF(ShadowMapSampler[3], input.vTexCoord[3], 3);
output.Color = float4(1, 0, 1, 1);
}


the output.Color assignments are for the debugging of split positions.

As for the scene setup, I would normally agree, but with real objects I feel like I have a better view of what the shadow should actually be. But maybe I'm just weird :)

Quote:




BTW, your returned matrix seems very strange.
You only have to apply the offset (bias) in the 'z' direction:

(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, shadowMapTexOffset, 1.0f); //or maybe -shadowMapTexOffset

Or I totally misunderstand something.



Hmm.. thanks, I'll take a look.

Share this post


Link to post
Share on other sites
Quote:
Original post by RobMaddison
I'm confused by your shadow maps, are you sure they're not inverted? Assuming your sun position is supposed to be behind your viewer's right shoulder, shouldn't the 1st shadowmap have the front of the car on the left of the image rather than the right?

Edit: plus I totally agree with szecs that getting shadow mapping working with simple geometry is far easier. I'd stick a few different sized cubes in instead of the lada and try again.


Interesting, I had not noticed that before. Thanks!

Ps. If I wouldn't have had the lada and had a cube instead, you would not have noticed this error :)

Share this post


Link to post
Share on other sites
Wait a bit!

I use this:

#define SHADOW_BIAS 0.4995f
...
float scale_x = 0.5*SCRN_WDTH/2048.0;//SM-size: 2048 x 2048, but I only use the srceen size portion
float scale_y = 0.5*SCRN_HGHT/2048.0;//you have '-' here, because the mirrored image


float biasMatrix[16] = {scale_x, 0.0f, 0.0f, 0.0f,
0.0f, scale_y, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
scale_x, scale_y, SHADOW_BIAS, 1.0f};

Try to work it out from this [rolleyes]

EDIT: okay I get it:
float biasMatrix[16] = {0.5, 0.0f, 0.0f, 0.0f,
0.0f, 0.5, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5, 0.5, SHADOW_BIAS, 1.0f};

Share this post


Link to post
Share on other sites
Quote:
Ps. If I wouldn't have had the lada and had a cube instead, you would not have noticed this error :)


Ah, but that's why you use different sized cubes! :)

Share this post


Link to post
Share on other sites
I'm sure now that the problem is with your returned matrix.
And cubes are better: it's easier to spot self-shadowing artifacts than in your complex scene.

It would have been easier to spot the real problem: the shadows are not cut off, but they are wrongly offseted and wrongly scaled in the light direction.

But I'm not totally sure yet.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!