Jump to content
  • Advertisement
Sign in to follow this  
treeway

Shadow Mapping

This topic is 4322 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've written a shadow mapping effect file based on the example from render monkey:
//--------------------------------------------------------------//
// Shadow Mapping
//--------------------------------------------------------------//

texture2D ShadowMap_Tex : RenderColorTarget
<
   float2 ViewportRatio= float2(1.0f,1.0f);
   string Format="D3DFMT_A8R8G8B8";
>;


sampler2D ShadowMap = sampler_state
{
   Texture = (ShadowMap_Tex);
   ADDRESSU = CLAMP;
   ADDRESSV = CLAMP;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
   MIPFILTER = LINEAR;
};


texture2D SpotLight_Tex
<
   string ResourceName = "Spotlight.jpg";
>;
sampler2D SpotLight = sampler_state
{
   Texture = (SpotLight_Tex);
   ADDRESSU = CLAMP;
   ADDRESSV = CLAMP;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
   MIPFILTER = LINEAR;
};


float4x4 proj_matrix : Projection;
float4x4 view_proj_matrix : WorldViewProjection;
float4 lightPos;
float4 view_position : CameraPosition;
float backProjectionCut = 2000.00000f;
float3 up = float3(0,1,0);
   
float distanceScale
<
   string UIName = "distanceScale";
   string UIWidget = "Numeric";
   float UIMin = 0.00;
   float UIMax = 1.00;
> = 0.00148f;

float shadowBias
<
   string UIName = "shadowBias";
   string UIWidget = "Numeric";
   float UIMin = 0.00;
   float UIMax = 0.01;
> = 0.004f;

struct VS_OUTPUT 
{
   float4 Pos: POSITION;
   float3 lightVec: TEXCOORD0;
};

VS_OUTPUT depth_vs_main(float4 inPos: POSITION)
{
   VS_OUTPUT Out;


   // Create view vectors for the light, looking at (0,0,0)
   float3 dirZ = -normalize(lightPos);
   float3 dirX = cross(up, dirZ);
   float3 dirY = cross(dirZ, dirX);

   // Transform into light's view space.
   float4 pos;
   inPos.xyz -= lightPos;
   pos.x = dot(dirX, inPos);
   pos.y = dot(dirY, inPos);
   pos.z = dot(dirZ, inPos);
   pos.w = 1;

   // Project the object into the light's view
   Out.Pos = mul(pos,proj_matrix);
   Out.lightVec = distanceScale * inPos;

   return Out;
}



float4 depth_ps_main(float3 lightVec: TEXCOORD0) : COLOR 
{
   // Output radial distance
   return length(lightVec);
}


//--------------------------------------------------------------//
// Object
//--------------------------------------------------------------//
struct object_VS_OUTPUT 
{
   float4 Pos:       POSITION;
   float3 normal:    TEXCOORD0;
   float3 lightVec : TEXCOORD1;
   float3 viewVec:   TEXCOORD2;
   float4 shadowCrd: TEXCOORD3;
};

object_VS_OUTPUT object_vs_main(
   float4 inPos: POSITION, 
   float3 inNormal: NORMAL)
{
   object_VS_OUTPUT Out;

   // Project the object's position
   Out.Pos = mul(inPos,view_proj_matrix);

   // World-space lighting
   Out.normal = inNormal;
   Out.lightVec = distanceScale * (lightPos - inPos.xyz);
   Out.viewVec = view_position - inPos.xyz;

   // Create view vectors for the light, looking at (0,0,0)
   float3 dirZ = -normalize(lightPos);
   float3 dirX = cross(up, dirZ);
   float3 dirY = cross(dirZ, dirX);

   // Transform into light's view space.
   float4 pos;
   inPos.xyz -= lightPos;
   pos.x = dot(dirX, inPos);
   pos.y = dot(dirY, inPos);
   pos.z = dot(dirZ, inPos);
   pos.w = 1;

   // Project it into light space to determine she shadow
   // map position
   float4 sPos = mul(pos,proj_matrix);

   // Use projective texturing to map the position of each fragment
   // to its corresponding texel in the shadow map.
   sPos.z += 10;
   Out.shadowCrd.x = 0.5 * (sPos.z + sPos.x);
   Out.shadowCrd.y = 0.5 * (sPos.z - sPos.y);
   Out.shadowCrd.z = 0;
   Out.shadowCrd.w = sPos.z;

   return Out;
}

float4 object_ps_main(
   float3 inNormal: TEXCOORD0, 
   float3 lightVec: TEXCOORD1, 
   float3 viewVec: TEXCOORD2, 
   float4 shadowCrd: TEXCOORD3) : COLOR 
{

   // Radial distance and normalize light vector
   float depth = length(lightVec);
   lightVec /= depth;


   // The depth of the fragment closest to the light
   float4 shadowMap;
   float  offset = (2.0/1024.0)*shadowCrd.w;
   shadowMap.x = tex2Dproj(ShadowMap, shadowCrd+float4(offset,0,0,0));
   shadowMap.y = tex2Dproj(ShadowMap, shadowCrd+float4(-offset,0,0,0));
   shadowMap.z = tex2Dproj(ShadowMap, shadowCrd+float4(0,offset,0,0));
   shadowMap.w = tex2Dproj(ShadowMap, shadowCrd+float4(0,-offset,0,0));

   // A spot image of the spotlight
   float spotLight = tex2Dproj(SpotLight, shadowCrd);

   // If the depth is larger than the stored depth, this fragment
   // is not the closest to the light, that is we are in shadow.
   // Otherwise, we're lit. Add a bias to avoid precision issues.
   float shadow;
   shadow = (float)(depth < shadowMap.x + shadowBias)/4.0;
   shadow += (float)(depth < shadowMap.y + shadowBias)/4.0;
   shadow += (float)(depth < shadowMap.z + shadowBias)/4.0;
   shadow += (float)(depth < shadowMap.w + shadowBias)/4.0;

   // Modulate with spotlight image
   float shadowval = spotLight*shadow;

   // Shadow any light contribution except ambient
   float4 colour =   shadowval;
     colour.w = 1.0f;
          
    return colour;
}




//--------------------------------------------------------------//
// Technique Section for Shadow Mapping
//--------------------------------------------------------------//
technique DepthPass
{
   pass Depth
   {
      VertexShader = compile vs_1_1 depth_vs_main();
      PixelShader = compile ps_2_0 depth_ps_main();
   }
}
technique ObjectPass
{
   pass Object
   {
      VertexShader = compile vs_1_1 object_vs_main();
      PixelShader = compile ps_2_0 object_ps_main();
   }

}



it seems okay execept for two problems: 1. all lights point at the origin i.e. 0,0,0. 2. the shadow cast on the ground seems to be the wrong way round. can anyone see why this is happening and can anyone suggest how i can add a target or direction to my lights? thanks.

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!