Sign in to follow this  

Another Shadow Map problem!

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

Hi, I have a big problem with my shadow map: As you can see, something strange is happening here. My approach is almost identical to Sepul's. The depth info is being rendered to the render target correctly. Its not that obvious from the little quad in the tope left of the scrrenshot but from other views the box can be clearly seen as darker than the floor (nearer) Heres some code:
// fx
//--------------------------------------------
// Global variables
//--------------------------------------------

float4x4	LightWVP			: WORLDVIEWPROJECTION;
float4x4	LightViewProj		: VIEWPROJECTION;
float4x4	World				: WORLD;
float4x4	WorldView			: WORLDVIEW;
float4x4	WorldViewProj		: WORLDVIEWPROJECTION;
float4x4	Projection			: PROJECTION;
float4x4	TextureProjection	: TEXTUREMATRIX;
float4x4	WorldIT				: WORLDINVERSETRANSPOSE;

vector	LightPos				: LIGHTPOSITION;
vector	EyePos					: EYEPOSITION;

// Light direction (view space)
float3 LightDirection < string UIDirectional = "Light Direction"; > = 
    normalize(float3(0.5, -0.5, 0));

// Light intensity
float4 ambient = { 0.0f, 0.0f, 0.0f, 1.0f };    // ambient

//--------------------------------------------
// Texture
//--------------------------------------------
texture			Shadow;					// shadowMap
texture			Skin;					// texture
//--------------------------------------------
// Samplers
//--------------------------------------------
sampler ShadowSampler = sampler_state 
{
    texture = (Shadow);
    AddressU  = CLAMP;        
    AddressV  = CLAMP;
    AddressW  = CLAMP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};
sampler SkinSampler = sampler_state 
{
    texture = (Skin);
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

//--------------------------------------------
// Shadow Creation
//--------------------------------------------
struct VSOUTPUT_SHADOW
{
	float4 Position	: POSITION;
	float Depth		: TEXCOORD0;
};
////////////////////////////////////////////////////////////////
VSOUTPUT_SHADOW VS_Shadow( float4 Position : POSITION )
{
	// Output struct
	VSOUTPUT_SHADOW OUT = (VSOUTPUT_SHADOW)0;
	
	float4 pos;

	LightWVP = mul( World, LightViewProj );
	pos = mul( Position, LightWVP );
	// Output the transformed position
	OUT.Position = pos;
	// Output the scene depth
	OUT.Depth = pos.z;
	
	return OUT;
}
/////////////////////////////////////////////////////////////////////
float4  PS_Shadow( VSOUTPUT_SHADOW IN ) : COLOR0
{
	return float4( IN.Depth,IN.Depth,IN.Depth,1.0f );
}

//--------------------------------------------
// Textured and Lit
//--------------------------------------------
struct VSOUTPUT_TEXTUREDANDLIT
{
    float4 Position		: POSITION;
    float4 Diffuse		: COLOR0;
    float2 Tex			: TEXCOORD0;
    float4 ShadowTex	: TEXCOORD1;
};
////////////////////////////////////////////////////////////////
VSOUTPUT_TEXTUREDANDLIT VS_TexturedAndLit(     
	float3 Position : POSITION,
    float3 Normal   : NORMAL,
  //  float3 Tangent  : TANGENT,
    float2 Tex		: TEXCOORD0 )
{
	// Output struct
	VSOUTPUT_TEXTUREDANDLIT OUT = (VSOUTPUT_TEXTUREDANDLIT)0;
	
	float3 L = -LightDirection;

  //  float4x4 WorldView = mul(World, View);

    float3 P = mul(float4(Position, 1),  (float4x3)WorldView);  // position (view space)
    float3 N = normalize(mul(Normal, (float3x3)WorldView)); // normal (view space)


    OUT.Position	= mul(float4(P, 1), Projection);             // position (projected)
    OUT.Diffuse		= ambient + max(0, dot(N, L)); // diffuse + ambient
    OUT.Tex			= Tex; 
    OUT.ShadowTex	= mul( Position, TextureProjection );   

    return OUT;
}
//////////////////////////////////////////////////////////////////////////
float4 PS_TexturedAndLit( VSOUTPUT_TEXTUREDANDLIT IN ) : COLOR
{
	
	// Grab the Skin term
	float4 SkinTerm = tex2D( SkinSampler, IN.Tex );

	// Grab the Shadow term
	float ShadowTerm = 0.0f;
	float A = tex2Dproj( ShadowSampler, IN.ShadowTex ).r;		// Depth in projected shadow map
	float B = (IN.ShadowTex.z - 0.1f);						// Depth of pixel with bias
		
	// Texel is shadowed
	ShadowTerm += A < B ? 0.2f : 1.0f;
	
	SkinTerm *= ShadowTerm;
	SkinTerm *= IN.Diffuse;
	
	return SkinTerm;

}


//--------------------------------------------
// Techniques
//--------------------------------------------
technique techShadow
{
	pass p0
	{
		Lighting	= False;
		CullMode	= none; //CCW;
		
		VertexShader = compile vs_2_0 VS_Shadow();
		PixelShader  = compile ps_2_0 PS_Shadow();
		//PixelShader  = NULL;
	}
}

technique techTexturedAndLit
{
	pass p0
	{
		Lighting	= False;
		CullMode	= CCW;
		
		VertexShader = compile vs_2_0 VS_TexturedAndLit();
		PixelShader  = compile ps_2_0 PS_TexturedAndLit();
	}
}

My hunch is that there is a problem with the texture projection matrix. Here's how I make it:
cLight::cLight()
{
	g_log->SIM( "cLight - constructing\n"  );

	m_range = 2000.0f;

	// Set the projection matrix.
	float farClip = 5000.0f;
	D3DXMatrixPerspectiveFovLH( &m_proj, D3DX_PI / 4, 1, 10.0f, farClip);
	// These are the magic lines which make it work!
	m_proj._33/=farClip;
	m_proj._43/=farClip;

	}
//////////////////////////////////////////////////////////////////////////////
void cLight::Update()
{
	// move light position with player
	g_lightPosition = g_network->GetPlayer()->GetProxyObject()->GetTranslation() 
				- ( g_lightDirection * m_range ); 

	m_light.Direction = g_lightDirection;

	// Update the view proj
	D3DXMatrixLookAtLH( &m_view, 
						&g_lightPosition, 
						&g_network->GetPlayer()->GetProxyObject()->GetTranslation(), 
						&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );

	// Compute the light-view-projection matrix
	m_viewProj =  m_view * m_proj;
	m_textureProjection = m_viewProj * g_simulation->GetShadowMap()->GetTextureMatrix();

}



//////////////////////


	//This is the the Texture Matrix referred to in the cLight::Update() call
	float Offset = 0.5f + (0.5f / (float)SHADOW_MAP_SIZE);
	ZeroMemory(&m_textureMatrix, sizeof(D3DXMATRIX));
    m_textureMatrix._11 =  0.5f;
    m_textureMatrix._22 = -0.5f;
    m_textureMatrix._33 =  1.0f;
    m_textureMatrix._41 =  Offset;
    m_textureMatrix._42 =  Offset;
    m_textureMatrix._44 =  1.0f;

// finally the renderer
		D3DXVECTOR4 tempVec = D3DXVECTOR4( g_lightDirection, 1.0f );
//		D3DXVECTOR4 tempVec = D3DXVECTOR4( g_simulation->GetLight()->GetForwardVector(), 1.0f );
	
		m_effect->SetTexture("Shadow", g_simulation->GetShadowMap()->GetShadowTexture() );
	
		D3DXMATRIX worldView, wvp, worldIT, T;
		D3DXMatrixMultiply( &worldView, &m_worldMatrix, g_camera->GetViewMatrixPtr() ); 
		m_effect->SetMatrix("WorldView", &worldView); 
		m_effect->SetMatrix("Projection", g_simulation->GetProjMatrixPtr() );
		D3DXMatrixMultiply( &T, &m_worldMatrix, g_simulation->GetLight()->GetTextureProjection() ); 
		m_effect->SetMatrix("TextureProjection", &T );
		D3DXMatrixMultiply( &wvp, &worldView, g_simulation->GetProjMatrixPtr() ); 
		m_effect->SetMatrix("WorldViewProj", &wvp );
		D3DXMatrixInverse( &worldIT, NULL, &m_worldMatrix );
		D3DXMatrixTranspose( &worldIT, &worldIT );
		m_effect->SetMatrix("WorldIT", &worldIT );
		

		m_effect->SetVector( "LightDirection", &tempVec);
		m_effect->SetVector( "LightPos", &D3DXVECTOR4( g_lightPosition, 1.0f ) );
		m_effect->SetVector( "EyePos", &D3DXVECTOR4( g_camera->GetTranslation(), 1.0f ) );
		//m_effect->SetFloatArray( "I_a", g_ambient, 4 );
		
		m_effect->SetTechnique("techTexturedAndLit"); 
		UINT numPasses;//, iPass;
		hr = m_effect->Begin( &numPasses, 0 );
	//	for( iPass = 0; iPass < numPasses; iPass ++ )
		hr = m_effect->BeginPass( 0 );

		// Render the object's mesh.
		m_mesh->Render( selected, m_effect );

		m_effect->EndPass();
		m_effect->End();





Has anyone had a similar problem? I am really stuck now! Thanks Simon

Share this post


Link to post
Share on other sites
Since my shadow map texture is looking good, then I must have a problem with the projective texturing used to cross reference between view and shadow map.

Heres the relevent bit:

float Offset = 0.5f + (0.5f / (float)SHADOW_MAP_SIZE);
ZeroMemory(&matTextureMatrix, sizeof(D3DXMATRIX));
matTextureMatrix._11 = 0.5f;
matTextureMatrix._22 = -0.5f;
matTextureMatrix._33 = 1.0f;
matTextureMatrix._41 = Offset;
matTextureMatrix._42 = Offset;
matTextureMatrix._44 = 1.0f;

This is used like this:

matTextureProjection = matWorld * matLightView * matLightProj * matTextureMatrix;


Is this the correct provcedure?

Thanks

Simon

Share this post


Link to post
Share on other sites

This topic is 4197 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this