Jump to content
  • Advertisement
Sign in to follow this  

Poor shadow mapping results

This topic is 2281 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'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:

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


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;
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;

Share this post

Link to post
Share on other sites
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:

dont mind that this is for dx10, the theory is the same.

Share this post

Link to post
Share on other sites
sorry for reposting - the second page is what might interest you:

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!