Jump to content
  • Advertisement
Sign in to follow this  
PatrizioTamorri

Shadow Map Shader Problem

This topic is 2721 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

Ok the problem is this:

i wrote a HLSL shader to get a simple shadow map (thinking to improve it in a ESM as i can get this to work)

the problem is that the shader seems correct...but the graphical results are not what i expect (lighted part and shadowed one are totally mad-positioned)


I use a directx 11 (with a lower D3D10_1 feature level as my card goes up only to that) and a shadow map 1024x1024

also i'm using no render target at all when rendering the depth map of the light,as i write out only the z buffer (which is then passed on as the depth texture).This process seems pretty correct as i can see in the bad output the silhouette of the rendered geometry...there is IMHO just a problem with the comparisons of the z values...
BUT WHAT??? XD



#define MAX_BONE_MATRICES 255
#define DEPTH_SCALE 1

Texture2D tx : register( t0 );
Texture2D light_shadow_map : register( t1 );



SamplerState Sampler : register(s0);

//normally it's enough
cbuffer cbuf : register( b0 )
{
float4x4 ViewProj;
}

//enter play when there is need for bone handling
cbuffer cbuf2 : register( b1 )
{
float4x4 BoneTrasform[MAX_BONE_MATRICES];
}

//used for light computations
cbuffer cbuf3 : register( b2 )
{
float4x4 shadow_view_projection;
float4 light_Pos;
}



struct VSDataIn
{
float4 Pos : POSITION;
float4 Normal : NORMAL;
float2 TexCoords : TEXCOORD0;
float weights : BLENDWEIGHT0;
float weights1 : BLENDWEIGHT1;
float weights2 : BLENDWEIGHT2;
float weights3 : BLENDWEIGHT3;
uint Bones : BLENDINDICES0;
uint Bones1 : BLENDINDICES1;
uint Bones2 : BLENDINDICES2;
uint Bones3 : BLENDINDICES3;
};

struct VSDataOut
{
float4 position : SV_POSITION;
float4 position2 : NORMAL;
float2 Tex : TEXCOORD0;

};

struct PSData_Shad
{
float4 target2 : SV_Target;
float target : SV_Depth;
};

struct PSData_Shad_In
{
float4 target : SV_Target;
};



//////////////////////vertex shader for shadow map

VSDataOut depth_VS(VSDataIn input)
{
VSDataOut output;
float4 Pos = 0;
Pos = input.weights * mul(input.Pos, BoneTrasform[input.Bones]);
Pos += input.weights1 * mul(input.Pos, BoneTrasform[input.Bones1]);
Pos += input.weights2 * mul(input.Pos, BoneTrasform[input.Bones2]);
Pos += input.weights3 * mul(input.Pos, BoneTrasform[input.Bones3]);
output.position2 = Pos;
output.Tex = input.TexCoords;
output.position = mul(shadow_view_projection,Pos);
return output;
}

//////////////PS for shadow map

PSData_Shad depth_PS(VSDataOut inp )
{
PSData_Shad output;
output.target2 = tx.Sample(Sampler, inp.Tex);
clip(output.target2.a - 0.1f); //clip all pixels with alpha less than 0.1
output.target = (inp.position.z / inp.position.w);
return output;
}




VSDataOut lighting_VS(VSDataIn input)
{
VSDataOut output = (VSDataOut)0;
float4 Pos = 0;
Pos = input.weights * mul(input.Pos, BoneTrasform[input.Bones]);
Pos += input.weights1 * mul(input.Pos, BoneTrasform[input.Bones1]);
Pos += input.weights2 * mul(input.Pos, BoneTrasform[input.Bones2]);
Pos += input.weights3 * mul(input.Pos, BoneTrasform[input.Bones3]);
output.position2 = Pos;
output.position = mul(ViewProj,Pos);
output.Tex = input.TexCoords;
return output;
}



float CalcShadowFactor(float4 projTexC)
{
projTexC.xyz /= projTexC.w;

if( projTexC.x < -1.0f || projTexC.x > 1.0f ||
projTexC.y < -1.0f || projTexC.y > 1.0f ||
projTexC.z < 0.0f )
return 0.0f;

projTexC.x = +0.5f*projTexC.x + 0.5f;
projTexC.y = -0.5f*projTexC.y + 0.5f;

// Depth in NDC space.
float depth = projTexC.z;

float litDepth = light_shadow_map.Sample(Sampler, projTexC.xy).r;

if(depth <= litDepth)
{
return 1.0f;
} else
{
return 0.0f;
}
}


////////PS for rendering using the shadow map already created

PSData_Shad_In lighting_PS(VSDataOut input)
{
PSData_Shad_In output;
float4 Pos = mul(shadow_view_projection,input.position2);
float shadow = CalcShadowFactor(Pos);
output.target.xyz = tx.Sample(Sampler, input.Tex).rgb;
output.target.xyz -= shadow; //subtract all light in case of shadows (else does nothing)
output.target.w = 1.0f; //just to be sure..
return output;
}


i know that there may be some unoptimized things (and i will be very happy if you point them out ;) as i may not know them) and some useless parameters (just playing around a bit to see what happend) but the logic seems just right to me...

Hope someone with better experience in this sector can help me ;)

Share this post


Link to post
Share on other sites
Advertisement
It looks like you keep switching how you do your vector/matrix transformations. In some places you do mul(vector, matrix) and in others you do mul(matrix, vector). I'm guessing this is due to row-major vs. column-major matrix issues. I would suggest that you start by making everything consistent. Since it doesn't look like you're using effects, the easiest way to do it is to just make sure your shader expect row-major matrices. This way you can just set row-major matrices into your constant buffer with no problems. You can do this by compiling your shaders with the D3D10_SHADER_PACK_MATRIX_ROW_MAJOR flag, or by marking your matrices with the "row_major" modifier in your shader code. Then you should use mul(vector, matrix) everywhere.

Share this post


Link to post
Share on other sites

#define MAX_BONE_MATRICES 255
#define DEPTH_SCALE 1

Texture2D tx : register( t0 );
Texture2D light_shadow_map : register( t1 );



SamplerState Sampler : register(s0);

//normally it's enough
cbuffer cbuf : register( b0 )
{
float4x4 ViewProj;
}
//enter play when there is need for bone handling
cbuffer cbuf2 : register( b1 )
{
float4x4 BoneTrasform[MAX_BONE_MATRICES];
}

//used for light computations
cbuffer cbuf3 : register( b2 )
{
float4x4 shadow_view_projection;
float4 light_Pos;
}



//------------------------------------------------------------------------------
// Depth Pass Shaders
// Simply output the depth of each pixel (you should clear the render target to 1.0f first)
// Can work with evry kind of texture buffer(even F16) best is ufloat32
//------------------------------------------------------------------------------



struct VSDataIn
{
float4 Pos : POSITION;
float4 Normal : NORMAL;
float2 TexCoords : TEXCOORD0;
float weights : BLENDWEIGHT0;
float weights1 : BLENDWEIGHT1;
float weights2 : BLENDWEIGHT2;
float weights3 : BLENDWEIGHT3;
uint Bones : BLENDINDICES0;
uint Bones1 : BLENDINDICES1;
uint Bones2 : BLENDINDICES2;
uint Bones3 : BLENDINDICES3;
};

struct VSDataOut
{
float4 position : SV_POSITION;
float4 position2 : NORMAL;
float2 Tex : TEXCOORD0;

};



struct PSData_Shad
{
float4 target2 : SV_Target;
float target : SV_Depth;
};

struct PSData_Shad_In
{
float4 target : SV_Target;
};





VSDataOut depth_VS(VSDataIn input)
{
VSDataOut output;
float4 Pos = 0;
Pos = input.weights * mul(input.Pos, BoneTrasform[input.Bones]);
Pos += input.weights1 * mul(input.Pos, BoneTrasform[input.Bones1]);
Pos += input.weights2 * mul(input.Pos, BoneTrasform[input.Bones2]);
Pos += input.weights3 * mul(input.Pos, BoneTrasform[input.Bones3]);
output.position2 = Pos;
output.Tex = input.TexCoords;
output.position = mul(Pos,shadow_view_projection);
return output;
}



PSData_Shad depth_PS(VSDataOut inp )
{
PSData_Shad output;
output.target2 = tx.Sample(Sampler, inp.Tex);
clip(output.target2.a - 0.1f); //clip all pixels with alpha less than 0.1
output.target = (inp.position.z / inp.position.w);
return output;
}




//------------------------------------------------------------------------------
// Lighting Pass Shaders
// check if a pixel is in shadow by doing the necessary comparisons
//------------------------------------------------------------------------------




VSDataOut lighting_VS(VSDataIn input)
{
VSDataOut output = (VSDataOut)0;
float4 Pos = 0;
Pos = input.weights * mul(input.Pos, BoneTrasform[input.Bones]);
Pos += input.weights1 * mul(input.Pos, BoneTrasform[input.Bones1]);
Pos += input.weights2 * mul(input.Pos, BoneTrasform[input.Bones2]);
Pos += input.weights3 * mul(input.Pos, BoneTrasform[input.Bones3]);
output.position2 = Pos;
output.position = mul(Pos,ViewProj);
Pos = output.position;
output.Tex = input.TexCoords;
return output;
}



float CalcShadowFactor(float4 projTexC)
{
projTexC.xyz /= projTexC.w;

if( projTexC.x < -1.0f || projTexC.x > 1.0f ||
projTexC.y < -1.0f || projTexC.y > 1.0f ||
projTexC.z < 0.0f )
return 0.0f;

projTexC.x = +0.5f*projTexC.x + 0.5f;
projTexC.y = -0.5f*projTexC.y + 0.5f;

// Depth in NDC space.
float depth = projTexC.z;

float litDepth = light_shadow_map.Sample(Sampler, projTexC.xy).r;

if(depth <= litDepth)
{
return 1.0f;
} else
{
return 0.0f;
}
}







PSData_Shad_In lighting_PS(VSDataOut input)
{
PSData_Shad_In output;
float4 Pos = mul(input.position2,shadow_view_projection);
float shadow = CalcShadowFactor(Pos);
output.target.xyz = tx.Sample(Sampler, input.Tex).rgb;
output.target.xyz -= 1- shadow;
output.target.w = 1.0f;
return output;
}



now it's all correct as i think and still getting the same output... :(
HELPP

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!