Jump to content
  • Advertisement
Sign in to follow this  
ekba89

Shadow map problem

This topic is 2533 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 using deferred shading and trying to create shadows but there is a little problem. Problem is if camera is in front of the light it works correct but when i move camera behind the light everywhere in the lights projection becomes shadow. I think it is easier to tell with images so here some screenshots. Also shadow area is smaller than light it is for testing purposes so don't worry about it. And here is the code for creating shadow. "position" variable is the world position and i'm sure it's true because everything where i use it works fine other than this. Also shadow_epsilon is 0.0005f. Thanks for replies.


float4x4 lightViewProjection = mul(xLightView, xLightProjection);
float4 projectedLightPosition = mul(position, lightViewProjection);
projectedLightPosition.x = (projectedLightPosition.x / projectedLightPosition.w) / 2 + 0.5f;
projectedLightPosition.y = -(projectedLightPosition.y / projectedLightPosition.w) / 2 + 0.5f;
projectedLightPosition.z /= projectedLightPosition.w;

if((saturate(projectedLightPosition).x == projectedLightPosition.x) && (saturate(projectedLightPosition).y == projectedLightPosition.y))
{
float depthInShadowMap = tex2D(ShadowMapSampler, projectedLightPosition.xy).r;
if(projectedLightPosition.z - SHADOW_EPSILON > depthInShadowMap)
{
return 0;
}
}

Share this post


Link to post
Share on other sites
Advertisement
I try to debug with pix and i found there is a problem with projectedLightPosition calculation. Actually it is a weird problem because everything other than w value of it is true and w is always 0.077. So any ideas why there is a problem with w value?

Share this post


Link to post
Share on other sites
[font="Arial"]I was trying to debug again and i saw depthInShadowMap is always 0 and projectedLightPosition.z is not between 0-1. I don't know if i'm using pix right i'm very new to it. As far as i understood gpu doesn't calculate values until it needs it so if it doesn't need it for some reason i see wrong results in pix. So don't rely on my debugging capabilities :D if you have any other opinion.[/font]

Share this post


Link to post
Share on other sites
Ok i'm not at home right now i'm going to post more code when i got home. Also thanks for reply i'm really frustrated because of this. I'm trying to solve it for 2 days.

Share this post


Link to post
Share on other sites
Are you sure the error is not in this line?

if((saturate(projectedLightPosition).x == projectedLightPosition.x) && (saturate(projectedLightPosition).y == projectedLightPosition.y))


You should also post the shadow creating shader and the lighting shader

Share this post


Link to post
Share on other sites
Ok i'm going to post that when i got home also i think there shouldn't be any problem because i tried to check if values are between 0 and 1 myself and got same result. Also i used shadow mapping with same "if" code before but not with deferred shading. And i'm sure position variable is true. I think there is something wrong with projection i mean i tried to multiply same position value that i got from pix with light's view projection matrices in cpu and they are different. Interesting thing is it can work according to my camera position although it should have nothing to do with my camera position. I'll post all related code in few hours i hope then we can find a solution. Thanks for reply by the way.

Share this post


Link to post
Share on other sites
Before i post all the code i tried to not rendering terrain in light's shadow map and it is kinda better than before. So maybe i shouldn't draw terrain in my shadow map should i? Here is all the related code and if you need to know other than these you can ask. Thanks.


void GetPositionAndNormal(out float4 position, out float3 normal, float2 texCoords)
{
float depth = tex2D(DepthMapSampler, texCoords).r;

// this is a special condition for skybox to not effected from lights. i make depth 0 in the depth map(g buffer's) when drawing skybox.
if(depth == 0)
{
position = float4(-1, -1, -1, -1);
return;
}

position.x = (texCoords.x * 2) - 1;
position.y = -((texCoords.y * 2) - 1);
position.z = depth;
position.w = 1.0f;

position = mul(position, xViewProjectionInv);
position /= position.w;

normal = tex2D(NormalMapSampler, texCoords).rgb;
normal = normalize((normal * 2) - 1);
}

float4 DSSpotLightPixel(DSVertexToPixel Input) : COLOR0
{
float4 OutputColor = 0;

float4 position;
float3 normal;
GetPositionAndNormal(position, normal, Input.TexCoords);
if(position.z == -1)
{
return 1;
}

float4x4 lightViewProjection = mul(xLightView, xLightProjection);
float4 projectedLightPosition = mul(position, lightViewProjection);
projectedLightPosition.x = ((projectedLightPosition.x / projectedLightPosition.w)) / 2.0f + 0.5f;
projectedLightPosition.y = -((projectedLightPosition.y / projectedLightPosition.w) / 2.0f) + 0.5f;
projectedLightPosition.z /= projectedLightPosition.w;

if(saturate(projectedLightPosition).x == projectedLightPosition.x && saturate(projectedLightPosition).y == projectedLightPosition.y)
{
float depthInShadowMap = tex2D(ShadowMapSampler, projectedLightPosition.xy).r;
if(projectedLightPosition.z - SHADOW_EPSILON > depthInShadowMap)
{
return 0;
}
}

float LightVal = max(0, dot(normal, -xLightDirection));

float3 lightDir = position.xyz - xLightPosition.xyz;

lightDir = normalize(lightDir);

float coneDot = dot(lightDir, xLightDirection);

if(coneDot >= cos(xLightAngle))
{
float coneAttenuation = pow(coneDot, xConeDecay);
OutputColor = LightVal * xLightPower * coneAttenuation * xLightColor;
}

return OutputColor;
}



//in the light class constructor.
D3DXCreateTexture(device->GetDevice(), device->GetBufferWidth(), device->GetBufferHeight(), 0, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &shadowMapTexture);
shadowMapTexture->GetSurfaceLevel(0, &shadowMapSurface);

//direction is now (0, -1, 0) for testing purposes so up vector is (1, 0, 0)
D3DXMatrixLookAtLH(&lightView, &position, &(position + direction), &D3DXVECTOR3(1, 0, 0));
D3DXMatrixPerspectiveFovLH(&lightProjection, angle, 1, 0.1f, 100.0f);



dxDevice->SetRenderTarget(sLight.shadowMapSurface, 0);
dxDevice->SetRenderTarget(NULL, 1);
dxDevice->SetRenderTarget(NULL, 2);
dxDevice->Clear();

effect->SetMatrix("xView", &sLight.lightView);
effect->SetMatrix("xProjection", &sLight.lightProjection);
terrain->DrawDepth(dxDevice, effect);
player->DrawDepth(dxDevice, effect);

/////HLSL
DepthVSToPixel DepthVS(float4 inPos : POSITION)
{
DepthVSToPixel Output = (DepthVSToPixel)0;

float4x4 preViewProjection = mul(xView, xProjection);
float4x4 preWorldViewProjection = mul(xWorld, preViewProjection);

Output.Position = mul(inPos, preWorldViewProjection);

Output.ScreenPosition = Output.Position;

return Output;
}

float4 DepthPS(DepthVSToPixel Input) : COLOR0
{
float4 Color = 0;

Color.r = Input.ScreenPosition.z / Input.ScreenPosition.w;

return Color;
}

Share this post


Link to post
Share on other sites
For example code on shadow mapping, check out this

http://www.d3dcoder.net/d3d10.htm

Download PartII, open chater 13 for the source.

Share this post


Link to post
Share on other sites
I'll check it out but i think something other than my shading code is wrong. Because i found there is a sample in Riemer's site (Chapter 6). I copied same shader code and got exact same result with before. So there can be something wrong with shadow map. Is there a way to see values in r32f texture? It looks plain white when you open it.

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!