Poor shadow mapping results

Started by
2 comments, last by hawksprite 12 years ago
I've been working on a shadow mapping technique in XNA recently and can't seem to produce quality results.

At first when I got shadows working they were terribly blockey and I read that I can help improve the quality by applying a gaussian blur to the shadow map.

Before Blur:
shadowmpaing4.png


The blur helped smooth them out but there were still plenty of artifacts and they flash a bit when I move.

smoothedShadows.png

I've been doing plenty of looking around and i'm still not sure what I can do differently.

The shader code for getting the depth:


struct VertexShaderOutputDepth
{
float4 position : POSITION;
float4 lPosition : TEXCOORD1;
float depth : TEXCOORD0;
};

float4 DepthPS(VertexShaderOutputDepth IN) : COLOR0
{
float moment1 = IN.lPosition.z/IN.lPosition.w;

return float4(moment1, moment1, moment1, 1.0f);
}

VertexShaderOutputDepth DepthVS( float4 inPos : POSITION)
{
VertexShaderOutputDepth Output = (VertexShaderOutputDepth)0;

Output.position = mul(mul(mul(inPos, xWorld), LightViewProj), shadowProjectionMatrix);
Output.lPosition = Output.position;

return Output;
}

technique Depth
{
pass Depth
{
ZEnable = true;
VertexShader = compile vs_3_0 DepthVS();
PixelShader = compile ps_3_0 DepthPS();
}
}


Blur for the map:


float4 PS_GaussianBlur(float2 texCoord : TEXCOORD) : COLOR0
{
float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);

for (int i = 0; i < KERNEL_SIZE; ++i)
color += tex2D(colorMap, texCoord + offsets) * weights;

return color;
}
--------------------------------------------------------------------------

technique GaussianBlur
{
pass Pass0
{
PixelShader = compile ps_2_0 PS_GaussianBlur();
}
}



I want to apologize for this one, its for drawing the heightmap with the shadows on it. However it hasn't been "cleaned" in a while and since I'm still learning HLSL it's pretty terrible right now.



PixelToFrame TexturedPS(VertexToPixel PSIn)
{
PixelToFrame Output = (PixelToFrame)0;

float specularPower = 1.5f;

////////////////////////////////////////////////////////////////////////////////////
// Generate the texture
Output.Color = tex2D(TextureSamplerSand, PSIn.TextureCoords) * float4(0.3f,0.3f,0.3f,1) * float4(specularPower,specularPower,specularPower,1);

if (PSIn.heightColor.r > 0){
float4 colorOverlay = tex2D(TextureSamplerDirt, PSIn.TextureCoords) *float4(0.8f,0.8f,0.8f,1);
Output.Color = lerp (Output.Color, colorOverlay, PSIn.heightColor.r);}
Output.Color += tex2D(TextureSamplerDirt, PSIn.TextureCoords) * PSIn.heightColor.g * float4(specularPower,specularPower,specularPower,1);
////////////////////////////////////////////////////////////////////////////////////

// Get normal information
float3 normalS = tex2D(normalSampler, PSIn.TextureCoords);
float4 normal = float4(normalS,1);
float3 ambientS = tex2D(ambientMapSampler, PSIn.TextureCoords);

// Finsh by blending the colors
if (useNormals){
Output.Color.rgb *= dot(normal,normal) * 0.4f;
}

// Depth of this pixel
float depth = PSIn.WorldSpace.z / maxDepth;
// Project there cordinates
float2 ProjectedTexCoords;
ProjectedTexCoords[0] = PSIn.WorldSpace.x/PSIn.WorldSpace.w/2.0f +0.5f;
ProjectedTexCoords[1] = -PSIn.WorldSpace.y/PSIn.WorldSpace.w/2.0f +0.5f;

// Get the depth out of the map
float diffuseLightingFactor = 1.0f;
if ((saturate(ProjectedTexCoords).x == ProjectedTexCoords.x) && (saturate(ProjectedTexCoords).y == ProjectedTexCoords.y))
{
float depthStoredInShadowMap = 0;
if (alias){
float aliasCount = 4;
float sizeKey = texelSize;
float sum = 0;

float2 offset1 = float2(sizeKey,0);
float2 offset2 = float2(-sizeKey,0);
float2 offset3 = float2(0,sizeKey);
float2 offset4 = float2(0,-sizeKey);

sum += PS_ShadowMapLookup(ShadowMapSampler, ProjectedTexCoords, offset1, 0);
sum += PS_ShadowMapLookup(ShadowMapSampler, ProjectedTexCoords, offset2, 0);
sum += PS_ShadowMapLookup(ShadowMapSampler, ProjectedTexCoords, offset3, 0);
sum += PS_ShadowMapLookup(ShadowMapSampler, ProjectedTexCoords, offset4, 0);

depthStoredInShadowMap = sum/aliasCount;
}
else{
depthStoredInShadowMap = PS_ShadowMapLookup(ShadowMapSampler, ProjectedTexCoords, float2(0,0), 0);;
}

float realDistance = PSIn.WorldSpace.z/PSIn.WorldSpace.w;
if ((realDistance - 1.0f/150.0f) <= depthStoredInShadowMap)
{
diffuseLightingFactor = dot(LightPosition2, PSIn.Position);
diffuseLightingFactor = saturate(diffuseLightingFactor);
diffuseLightingFactor *= 1.5f;
diffuseLightingFactor = 0.2f;
}
}




Output.Color.rgb *= (float3(diffuseLightingFactor,diffuseLightingFactor,diffuseLightingFactor));


return Output;
}
Advertisement
i dont know if i understand you correctly, but did you blur the shadow map itself? This will not work as the shadow map only stores the depth of the scene as seen from the light source and not the shadow itself. The easiest solution to get softer shadows is PCF filtering.

A good description can be found here:
http://takinginitiative.net/2011/05/15/directx10-tutorial-10-shadow-mapping/

dont mind that this is for dx10, the theory is the same.
sorry for reposting - the second page is what might interest you:
http://takinginitiative.net/2011/05/25/directx10-tutorial-10-shadow-mapping-part-2/
Thanks for the reply, i'll look into that method and post results.

This topic is closed to new replies.

Advertisement