Shadow mapping problem (depth texture)

Started by
8 comments, last by Etus 15 years, 1 month ago
Hi, I'm currently trying to implement a shadow mapping system in my engine, and I ran into a problem. I tried searching the forums and internet for a solution but couldn't find one. The problem I think is with the texture created after the first pass - the pass in which I render the world from the light view. Basically I set the worldViewProjection matrix to the light's one and render the geometry with an effect.

struct ShadowPS_Input {
  float4 Pos: Position;
  float2 Pos2D : TEXCOORD0;
};

ShadowPS_Input VS_ShadowMap(float4 Pos : POSITION, float3 Norm : NORMAL) {

  ShadowPS_Input output;
  //Pos.xyz += Norm.xyz * 0.1f;
  float4 outPos = mul(Pos, worldViewProjectionMatrix);
  output.Pos = outPos;
  outpus.Pos2D.xy = outPos.zw;

  return output;

}

float4 PS_ShadowMap(ShadowPS_Input IN) : COLOR {

  float4 cColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
  cColor.r = IN.Pos2D.x / IN.Pos2D.y;
  return cColor;

}

This is the vs and ps I use. The render target is ofcourse a R32F texture format. The problem is that when I look at the texture (I save it using D3DXSaveTexture as dds) all the objects are white - meaning the ps outputs them as being far away from the light view instead of grayscaling objects which are closer. I looked at this article http://wiki.gamedev.net/index.php/D3DBook:Shadow_Maps And there he does "IN.Pos2D.x / maxDepth". I tried that, which works (the texture looks ok than), but I don't understand why he does that instead of dividing by the w componenet. Any help is much appreciated. Sorry for any English mistakes btw... Thanks, Yuval
Advertisement
The texture will almost certainly look white because it's a floating point texture--any value of 1 or higher will look white.

Have you actually tried the shadow mapping effect to see if the depth comparison works?
Mmm, that could be the case. I thought that DirectX Texture Tool / Photoshop can detect the dds file format and show me any subtle changes in the pixels values.

Well, the shadow mapping itself works well. The objects in the world cast shadows on the terrain, but *not* on one another. That's why I thought there might be a problem with the shadow texture map.

Any idea what that could be?
When I don't apply any bias at all to the shadow test, the objects shadow themselves(and create a lot of wrong looking artifacts) but not one another. So I applied a bias and that solved the self-shadowing problem, but they still don't cast shadow on each other. Any idea?

Thanks!
Is your FOG rendering state disabled? This can be a problem if you are using shader model 2.0 or lower.
Yeah, it's disabled. Also - I'm targetting at vs/ps 3.0.
Without seeing the shader code and/or screenshot i cant say much...other than I suspect there is something wrong with your bias or something.
I understand, thanks. I'll post the code on monday, I'm not at work right now and I have it on my computer there.
Etus,
The missing self shadowing could be caused by the bias your are applying to get rid of the artifacts.

I've seen this effect in my own shadow mapping where increasing the bias to get rid of artifacts caused part of the shadowing to disappear. I had a plane populated with domes ( example 1 , notice the wrong shadows cast by the domes and the only partial self-shadowing in the wooden frame) where increasing the bias to get rid of the surface acne caused part of the dome to not cast a shadow on the plane.

The only way I found to get rid of these problems is to remove the annoying bias technique altogether and implement second depth shadow maps. This works perfectly but induces more overhead in the shadow map generation process :

example 2

This is not a problem if your scene is static as the map needs to be generated only when the light changes or a shadow casting object moves

You may also be interested in this thread :

http://www.gamedev.net/community/forums/topic.asp?topic_id=525295

Regards,
EBrarian

[Edited by - ebrarian on February 21, 2009 8:27:45 AM]
Ok, I got the code and a screenshot:

Link to Screenshot

This is the vertex and pixel shaders:

VS_OUTPUT_GENERAL VS_LGeneral(VS_INPUT_GENERAL IN){	VS_OUTPUT_GENERAL OUT;	float3 worldNormal = mul(float4(IN.normal,0), worldInverseTransposeMatrix);	float4 pWorld = mul(float4(IN.position,1), worldMatrix);				OUT.diffuseVertexColor.rgb = Shade(pWorld.xyz, worldNormal).xyz;	OUT.vPos = mul(pWorld, lightWorldViewProjectionMatrix);	OUT.position = mul(float4(IN.position,1), worldViewProjectionMatrix);	OUT.baseTexCoord = IN.baseTexCoord;	return OUT;}#define SMAP_SIZE 1024#define SHADOW_BIAS 0.005ffloat4 PS_LGeneral(VS_OUTPUT_GENERAL IN) : COLOR{	float2 shadowTexCoords = float2(0.0f, 0.0f);	shadowTexCoords.x = IN.vPos.x / IN.vPos.w;	shadowTexCoords.y = -IN.vPos.y / IN.vPos.w;	shadowTexCoords += 1.0f;	shadowTexCoords *= 0.5f;	// transform to texel space	float2 texelpos = SMAP_SIZE * shadowTexCoords;	float realDist = IN.vPos.z / IN.vPos.w;        	// Determine the lerp amounts           	float2 lerps = frac( texelpos );	//read in bilerp stamp, doing the shadow checks	float sourcevals[4];	sourcevals[0] = (tex2D(shadowMap, shadowTexCoords).r >= realDist - SHADOW_BIAS)? 0.0f: 1.0f;  	sourcevals[1] = (tex2D(shadowMap, shadowTexCoords + float2(1.0/SMAP_SIZE, 0) ).r >= realDist - SHADOW_BIAS)? 0.0f: 1.0f;  	sourcevals[2] = (tex2D(shadowMap, shadowTexCoords + float2(0, 1.0/SMAP_SIZE) ).r >= realDist - SHADOW_BIAS)? 0.0f: 1.0f;  	sourcevals[3] = (tex2D(shadowMap, shadowTexCoords + float2(1.0/SMAP_SIZE, 1.0/SMAP_SIZE) ).r >= realDist - SHADOW_BIAS)? 0.0f:1.0f;          	// lerp between the shadow values to calculate our light amount	float lightAmount = lerp( lerp( sourcevals[0], sourcevals[1], lerps.x ),                               lerp( sourcevals[2], sourcevals[3], lerps.x ),                               lerps.y );	float4 baseTexColor;	baseTexColor = tex2D(baseMap, IN.baseTexCoord);	baseTexColor.xyz *= IN.diffuseVertexColor;	baseTexColor.xyz *= lightAmount;	return baseTexColor;	}


As you can see in the screenshot, the trees drop correct shadows on the terrain - but not on one another.
When I play with the bias, I can get models to shadow one another - but than they also self-shadow. Any ideas on what am I doing wrong?

Thanks for all the replies so far.
ebrarian, I looked at your screenshots and I'm not sure that you have the same problem I get. Your dome might not project shadows correctly, but the wooden model for example casts shadows on the spheres. But I'll take a look at the thread you pointed out, thanks.

This topic is closed to new replies.

Advertisement