Jump to content

  • Log In with Google      Sign In   
  • Create Account


[DX9} Cubic Shadow Mapping


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.

  • You cannot reply to this topic
18 replies to this topic

#1 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

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 ShadowMapVertexShader( float4 inPos : POSITION)

{

SMapVertexToPixel Output = (SMapVertexToPixel)0;



Output.Position = mul(inPos, xLightWorldViewProjection);

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



return Output; 

}

SMapPixelToFrame ShadowMapPixelShader(SMapVertexToPixel PSIn)

{

SMapPixelToFrame Output = (SMapPixelToFrame)0;

float fDepthValue = PSIn.Depth; 

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



return Output;

}

technique ShadowMap

{

pass Pass0

{

VertexShader = compile vs_2_0 ShadowMapVertexShader();

PixelShader = compile ps_2_0 ShadowMapPixelShader();

}

}

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

float DepthColour = texCUBE(ShadowMapSampler, normalize(LightDirection.xyz)).x;



if ((Distance + 0.001f) > DepthColour)

{
not in shadow

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.

Sponsor:

#2 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

Posted 21 March 2011 - 06:50 AM

Anyone know anything about Shadow Mapping here?

#3 Dawoodoz   Members   -  Reputation: 290

Like
0Likes
Like

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.

My open source DirectX 10/11 graphics engine. https://sites.google.com/site/dawoodoz

"My design pattern is the simplest to understand. Everyone else is just too stupid to understand it."


#4 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

Posted 21 March 2011 - 02:26 PM

Wow... I'm even more confused.

Here are some images that I hope will help:

Posted Image

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





Posted Image

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.





Posted Image

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?


#5 TiagoCosta   Crossbones+   -  Reputation: 1863

Like
1Likes
Like

Posted 21 March 2011 - 02:57 PM

When you create the shadow map you should to this:
Vertex shader:
float4 positionWS = mul( inPos, worldMat );
output.positionLWVP = mul( inPos, worldViewProjMat );
    
output.lightVec = lightPosition - positionW.xyz;

return output;

[EDITED]Pixel shader:
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;

if(distance > shadowMapDepth + 0.0001f) 
{ 	
 	
}  

Tiago Costa
Aqua Engine - my DirectX 11 game "engine" - In development

#6 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

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?

#7 TiagoCosta   Crossbones+   -  Reputation: 1863

Like
1Likes
Like

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

Tiago Costa
Aqua Engine - my DirectX 11 game "engine" - In development

#8 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

Posted 21 March 2011 - 06:23 PM

I made the change to the shader for the shadow map and this is what I have for the light shader:

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:

Posted 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.

#9 TiagoCosta   Crossbones+   -  Reputation: 1863

Like
0Likes
Like

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...
Tiago Costa
Aqua Engine - my DirectX 11 game "engine" - In development

#10 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

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?

#11 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

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.



#12 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

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

#13 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

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:

Posted Image



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.

Posted Image


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.

#14 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

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.

Posted Image



Anyone ever have this problem before?






#15 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

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?



#16 solenoidz   Members   -  Reputation: 514

Like
0Likes
Like

Posted 24 March 2011 - 01:21 PM

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

#17 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

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?

#18 DJTN   Members   -  Reputation: 207

Like
0Likes
Like

Posted 25 March 2011 - 09:29 AM

AnyOne?



#19 DJTN   Members   -  Reputation: 207

Like
1Likes
Like

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.



PARTNERS