Jump to content
  • Advertisement
Sign in to follow this  
martinperry

PSSM / CSM shadows

This topic is 3162 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 am trying to implement PSSM (http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html - I implemented Scene-Independent method for now) Inspiration for me was also this article: http://hax.fi/asko/PSSM.html But I dont know, what i am doing wrong. I got this. Shadow error - light goes from left part of the image. Shadow is white. But I have left side of car "in shadow" and shadow also on lightened side of car I think, that my C# impl. should be correct. But maybe my HLSL code is wrong. (Map generation works fine, I use code from Standard one SM generation)
Texture xShadowMapText0;
Texture xShadowMapText1;
Texture xShadowMapText2;
sampler ShadowMapSamplerPssm[3] = {
	{sampler_state { Texture = <xShadowMapText0> ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=NONE; AddressU = clamp; AddressV = clamp;}},
	{sampler_state { Texture = <xShadowMapText1> ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=NONE; AddressU = clamp; AddressV = clamp;}},
	{sampler_state { Texture = <xShadowMapText2> ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=NONE; AddressU = clamp; AddressV = clamp;}}
};

struct PSSMVertexToPixel 
{
	float4 Position		: POSITION;	
	float3 Normal 		: TEXCOORD0;
	float3 Position3D   : TEXCOORD1;
	float2 TexCoords    : TEXCOORD2;
	float4 texCoord[3 + 1] : TEXCOORD3;
	
};

struct PSSMPixelToFrame
{
	float4 Color	:	COLOR0;
};


PSSMVertexToPixel RenderPSSMSceneVS( float4 inPos : POSITION, float2 inTexCoords : TEXCOORD0, float3 inNormal : NORMAL)
{
	PSSMVertexToPixel Output = (PSSMVertexToPixel)0;
    
	float4 posInWorld = mul(inPos, xWorld); 
	Output.Position = CalcPositionInWorld(inPos);
	
	
	Output.texCoord[0] = mul(posInWorld, xCamView);
	for (int i = 0; i < 3; i++)
	{
		Output.texCoord[i + 1] = mul(posInWorld, textureMatrix);
	}
	
	//--- if i want to use textures later
	Output.TexCoords = inTexCoords;
	Output.Normal = normalize(mul(inNormal, xWorld));
	Output.Position3D = mul(inPos, xWorld);
	
	return Output;
}

PSSMPixelToFrame RenderPSSMScenePS(PSSMVertexToPixel PSIn)
{
	PSSMPixelToFrame Output = (PSSMPixelToFrame)0;

//Nvidia part of code
	float light = 1.0f;
	float distance = PSIn.texCoord[0].z / PSIn.texCoord[0].w;
	for(int i = 0; i < 3; i++)  
    {  
     	if(distance < splitPlane)  
		 
		{  
			float depth = PSIn.texCoord[i+1].z / PSIn.texCoord[i+1].w;  
		   	float depthSM = tex2Dproj(ShadowMapSamplerPssm, PSIn.texCoord[i + 1]);  
 
			light = (depth < depthSM) ? 1.0f : 0.5f; 
		   	break;  
		}  
    }  
	Output.Color = light;
	
	return Output;
}


technique PSSM
{
	pass Pass0
	{
		//CullMode = CCW; //doesnt effect
		VertexShader = compile vs_2_0 RenderPSSMSceneVS();
		PixelShader = compile ps_2_0 RenderPSSMScenePS();
	}
}



Share this post


Link to post
Share on other sites
Advertisement
Quote:

Maybe bias issue, do you have any depth bias added during depth compare?


No.. I don´t added any bias. Where should I put that ?
To this line: if(distance < splitPlane) ?

Share this post


Link to post
Share on other sites
Nope, here:
light = (depth < depthSM) ? 1.0f : 0.5f;

due limited precision of stored depth that expression will be true in many cases. So try something like this:
light = (depth < (depthSM + 0.001)) ? 1.0f : 0.5f;

Share this post


Link to post
Share on other sites
No.. it has no effect ;(

Maybe my crop matrix calc. is wrong. I calc that matrix this way.

Matrix lightViewProjection = lightViewMatrix * lightProjectionMatrix;

/*
BoundingBox box = BoundingBox.FromPoints(frustrumCorners);
frustrumCorners = box.GetCorners();
*/


Vector3[] transformedCorners = new Vector3[frustrumCorners.Length];
for (int i = 0; i < this.corners.Length; i++)
{
Vector4 tmp = Vector3.Transform(frustrumCorners, lightViewProjection);
transformedCorners.X = tmp.X / tmp.W;
transformedCorners.Y = tmp.Y / tmp.W;
transformedCorners.Z = tmp.Z / tmp.W;
}

cropBox = BoundingBox.FromPoints(transformedCorners);

//cropBox = BoundingBox.FromPoints(this.corners);
//Console.WriteLine("" + cropBox + "|***|");
cropBox.Minimum.Z = 0.0f;


float scaleX, scaleY, scaleZ;
float offsetX, offsetY, offsetZ;

scaleX = 2.0f / (cropBox.Maximum.X - cropBox.Minimum.X);
scaleY = 2.0f / (cropBox.Maximum.Y - cropBox.Minimum.Y);
scaleZ = 1.0f / (cropBox.Maximum.Z - cropBox.Minimum.Z);

offsetX = -0.5f * (cropBox.Maximum.X + cropBox.Minimum.X) * scaleX;
offsetY = -0.5f * (cropBox.Maximum.Y + cropBox.Minimum.Y) * scaleY;
offsetZ = -cropBox.Minimum.Z * scaleZ;

Matrix cropMatrix = Matrix.Identity;
cropMatrix.M11 = scaleX;
cropMatrix.M22 = scaleY;
cropMatrix.M33 = scaleZ;

cropMatrix.M41 = offsetX;
cropMatrix.M42 = offsetY;
cropMatrix.M43 = offsetZ;

return cropMatrix;





And with this crop matrix I simply do this
textureMatrix = Matrix() * TexScaleMatrix

and texture matrix goes to shader.

[Edited by - martinperry on October 30, 2009 2:19:29 PM]

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!