• FEATURED

View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

18 replies to this topic

### #1DJTN  Members

Posted 20 March 2011 - 04:10 PM

I've been working on implementing Shadow Mapping for Point Lights for weeks now and I still do not have a shadow being drawn. Ive looked at tons of threads on the subject and the tutorials but seems I'm just not getting it. I either get everything drawn in shadow (black) or no shadow at all (current situation). Maybe someone here can point me in the right direction...

First I create a cube texture (6 sides). I render my scene with the following shader:

float4x4 xLightWorldViewProjection;

float4x4 xLightWorldView;

float xMaxDepth;

struct SMapVertexToPixel

{

float4 Position : POSITION;

float3 Depth : TEXCOORD0;

};

struct SMapPixelToFrame

{

float4 Color : COLOR0;

};

{

SMapVertexToPixel Output = (SMapVertexToPixel)0;

Output.Position = mul(inPos, xLightWorldViewProjection);

Output.Depth = length(mul(inPos, xLightWorldView).xyz);

return Output;

}

{

SMapPixelToFrame Output = (SMapPixelToFrame)0;

float fDepthValue = PSIn.Depth;

Output.Color = float4(fDepthValue, fDepthValue, fDepthValue, 1.0f);

return Output;

}

{

pass Pass0

{

}

}


I've seen the cube texture and it's getting rendered. As I move the light around I see the white square moveing in and out of each texture.

Then, when I draw my scene again, I pass the CubeTexture to my shader and sample it:



float4 texel = 0.0f;

[/size]float4 LightDirection = 0.0f;

LightDirection.xyz = input.Position.xyz - LightPosition;

float Distance = length( LightDirection.xyz );

if ((Distance + 0.001f) > DepthColour)

{

texel = tex2D(texsampler, input.TexCoords);

}


With this code, everything gets drawn as normal, no shadows though

I think my problem may be in the light shader but I'm not sure.

### #2DJTN  Members

Posted 21 March 2011 - 06:50 AM

### #3Dawoodoz  Members

Posted 21 March 2011 - 09:28 AM

When making depth based shadows, you only render to a depth buffer by giving NULL as the color buffer. Only the vertex buffer's transformation and optional alpha clipping in the pixel shader is important since the color will not be saved.
A large single channel atlas will be used as input to the lights in the material shaders using shader resource views. When rendering to it, assign parts of it as the depth buffer with many depth stencil views.
Give the near and far clip planes from each camera as argument to the shaders that are making the comparison so that the depth to the light source can be compared with the real depth by lerping the [0..1] values with near and far depths.
To see if things are working, draw the depth atlas as images to the screen so that you divide the problem in half.

"App". is an acronym and must always be followed by a dot.

### #4DJTN  Members

Posted 21 March 2011 - 02:26 PM

Wow... I'm even more confused.

Here are some images that I hope will help:

In this 1st image I've added a basic box.

In the 2nd image I've added a point light, right on top of the box. You'll also notice the 6 faces of the texture cube at the top left of the image. This is the shadow cube I'm sending to the lighting pixel shader. As you can see there are no shadows.

In this 3d image I've moved the light up a bit off the box. You can see it's trying to create the shadows but they are a mess and that is my problem.

I don't think my problem is creating the shadow maps. I could be wrong, but i think the problem is in my light/material PS code.

I'm using the light position in world space to get the light direction:
float3 lightDir = normalize(input.WorldPos - LightPosition);

I then calculate the Depth like this:
float pixelLightDepth = length(lightDir);

Sampling the texturecube I get the depth in the shadow map
float StoredDepthInShadowMap = texCUBE(ShadowMapSampler, normalize(float4(-(lightDir), 0.0f))).x;

I then compare the light depth with the shadowmap depth:
if ((pixelLightDepth ) <= StoredDepthInShadowMap)  {texel = float4(0,0,0,1); }

Am I missing something here? or am I sampling and comparing depths wrong?

### #5TiagoCosta  Members

Posted 21 March 2011 - 02:57 PM

When you create the shadow map you should to this:
float4 positionWS = mul( inPos, worldMat );
output.positionLWVP = mul( inPos, worldViewProjMat );

output.lightVec = lightPosition - positionW.xyz;

return output;


float fDepthValue = length(PSIn.lightVec);

Output.Color = float4(fDepthValue, fDepthValue, fDepthValue, 1.0f);


And then sample the cubic shadow map like this:
lightDirection.xyz = lightPosition.xyz – positionWS
float distance = length(lightDirection.xyz);
lightDirection.xyz = lightDirection.xyz / distance;

float smDepth = texCUBE(ShadowMapSampler, float4(-(lightDirection.xyz), 0.0f)).x;

{

}


### #6DJTN  Members

Posted 21 March 2011 - 05:13 PM

Thanks Tiago. I tried what you said and I'm still getting the same results just smaller, very smaller.

In your code in the sampler you have:
lightDirection.xyz = lightPosition.xyz – positionWS;


What is positionWS? I've been muling input.Position and the world matrix in my vertex shader and passing that in. I would assume this is incorrect and may be my problem.

Here is what I have for the Sampling in my light/material PS:

LightPosition is the lights position in worldspace...


float3 lightDirection = LightPosition - input.WorldPos;

float distance = length(lightDirection);

lightDirection = lightDirection / distance;

float smDepth = texCUBE(ShadowMapSampler, float4(-(lightDirection.xyz), 0.0f)).x;

if(distance < smDepth + 0.0001f)



What is positionWS?

### #7TiagoCosta  Members

Posted 21 March 2011 - 05:34 PM

PositionWS is the current pixel Position in World Space...

By the way:
if you normalize lightDir:
float3 lightDir = normalize(input.WorldPos - LightPosition);
float pixelLightDepth = length(lightDir);

The length of lightDir will always be 1.0f.

Im sorry, in my previous code I did a mistake:
In the pixel shader that you use to create the shadow map I wrote;
float fDepthValue = PSIn.lightVec;


but it should be:
  float fDepthValue = length(PSIn.lightVec);


### #8DJTN  Members

Posted 21 March 2011 - 06:23 PM

float4 texel = tex2D(texsampler, input.TexCoords);
float3 lightDirection = LightPosition - input.WorldPos;
float distance = length(lightDirection);
lightDirection = lightDirection / distance;

float smDepth = texCUBE(ShadowMapSampler, float4(-(lightDirection.xyz), 0.0f)).x;

if(distance < smDepth + 0.001f)
{
texel =  float4(0,0,0,1);
}

I'm getting a small round shadow when the light is almost completely touching the box.
You can see it in this image:

If the light is any futher away it dissapears completely.
What would cause it to be so small? Any idea's why I cant get this to work?

BTW - thanks for your help.

### #9TiagoCosta  Members

Posted 22 March 2011 - 10:34 AM

If the light is any futher away it dissapears completely.
What would cause it to be so small? Any idea's why I cant get this to work?

When you create the projection matrix, use a higher value in the zFar parameter...

### #10DJTN  Members

Posted 22 March 2011 - 12:16 PM

If the light is any futher away it dissapears completely.
What would cause it to be so small? Any idea's why I cant get this to work?

When you create the projection matrix, use a higher value in the zFar parameter...

Didn't change anything ,ugg...

When I'm drawing my shadowmap I'm setting the device world tranform like I would normally do before drawing the box in a normal render with Scale, Rotation and Position. For the device transform view I'm using the Light's view. I then pass in the shader param "xLightWorldViewProjection" with device world transform * the light's view projection. The light's view projection is based off the cube face I'm rendering and the lights position. I then multiply that by PerspectiveFovLH(PI / 2, 1.0f, 1f, 1000f).

Is this correct?

### #11DJTN  Members

Posted 22 March 2011 - 03:23 PM

My shadow maps look like they should but my distance in the light/material shader is always larger than my depth test into my shadowmap.

### #12DJTN  Members

Posted 22 March 2011 - 05:08 PM

When you create the projection matrix, use a higher value in the zFar parameter...

Again Tiago, thanks for your help. I changed my texture cube's format to R32F and I'm getting much better results. I also started manually creating each face for the cube so I could actually see what getting rendered to it and made significant improvements with that as well.

I'm almost there, I have the shadows being drawn in the wrong direction. For example, if I have the box a couple of feet off the floor and the light under it, I can see the box's shadow on the floor. Kind of weird but at least I made improvements today. I'll see if I can figure that out tomorrow morning.

When I'm done I'll post some information here in hopes that no one else has to go through what I did to get simple shadows.

Cheers,
Dj

### #13DJTN  Members

Posted 23 March 2011 - 01:38 PM

Still having issues and I cannot figure out why. I hope some one, anyone can point me in the right direction.

If the light is on the ground plane in front of the box it draws the shadow from the light to thebox:

If the light moves to the left of the box or any where around it for that matter, the shadows act like a light source.

Any one have any idea's? Am I creating my shadow maps with the wrong tansformations? I've tried several different scenereos and still no change. The shadow is always on the side of the light source.

### #14DJTN  Members

Posted 23 March 2011 - 04:35 PM

Well I got the shadow on the correct side by changing the XLightWorld from my world matrix to the world matrix * the Light's view matrix but now I have another problem. The box is included in the shadow.

Anyone ever have this problem before?

### #15DJTN  Members

Posted 24 March 2011 - 12:10 PM

Umm ok, no one here to help... Maybe someone could at least tell me another forum where I might get some help?

### #16solenoidz  Members

Posted 24 March 2011 - 01:21 PM

Try playing around with this value
if(distance < smDepth + 0.001f)

### #17DJTN  Members

Posted 24 March 2011 - 02:47 PM

Try playing around with this value
if(distance < smDepth + 0.001f)

If I increase the value there is a large round shadow on the floor whcih eventually encapsulates the box as I move the light closer to the box. if I decrease the value, even subtract it, it skrinks the shadow that the box is in and also the one the box is projecting on the floor mesh.

I was under the impression that cubic shadow mapping allowed an object to be the shadow caster and receiver in one render call, through sampling the depth texture. Am I wrong in this assumption? Do I have to render the shadow maps for every object I render normally, omitting that object so it's not in it's own shadow?

I create my shadow maps (cubic) by rendering everything in the scene through my shadow map shader to a surface (texture). Then I pass that texture to the shaders that I use to render my scene normally. Currently, if the object that I'm rendering "normally" is also in the shadow map render, then it's in its own shadow. Is my issue a draw order issue or does shadow mapping allow for casting AND receiving shadows?

### #18DJTN  Members

Posted 25 March 2011 - 09:29 AM

AnyOne?

### #19DJTN  Members

Posted 29 March 2011 - 12:27 PM

I've figured this out on my own. For those of you struggeling with cubic shadow mapping, TiagoCosta's PS code does work but it's the basic building block. You'll have to massage the code to work with your existing engine/app. To keep my box from being completely encapsulated in a shadow, I added ObjectID's in the green channel of the texture and then checked the ID's when rendering the box normally. This gives me the flexability to mark an object as caster and/or receiver and also allows for objects to shadow each other.

I'm still having issues with jagged edges and trying to soften the shadows without increasing memory usage but it's a fine line you have to ballance.

I chose Shadow Mapping because of it's simplicity, low-CPU overhead and it's ability to handle trasnparency like tree's and billboards - something very difficult with shadow volumes. On the down side, shadow mapping is very hardware dependant - R32 texture format and cube texture for point lights - (that's 6 textures). The larger your textures, the better the shadow accuracy but at a cost.

Thanks to TiagoCosta for his help. I'll continue to watch this post in the event I could help someone else.

Regards,
Dj

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.