Hi guys
Ive been experimenting with shadow casting using riemers tutorials as a guide(link below) but at this point Im stuck
because Im not sure what adjustments are needed in order to cast a shadow from my car model onto the
terrain, if anyone can show me what Im not doing or doing wrong it would be much appreciated.
Thankyou
riemers link
http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series3/Real_shadow.php
below is what I have so far:
[attachment=18844:11 20 2013 4 06 16 PM.jpeg]
shadowmap hlsl code
struct SMapVertexToPixel
{
float4 Position : POSITION;
float4 Position2D : TEXCOORD0;
};
struct SMapPixelToFrame
{
float4 Color : COLOR0;
};
//xMaxDepth;
SMapVertexToPixel ShadowMapVertexShader( float4 inPos : POSITION)
{
SMapVertexToPixel Output = (SMapVertexToPixel)0;
Output.Position = mul(inPos, xlightsWorld);
Output.Position2D = Output.Position;
return Output;
}
SMapPixelToFrame ShadowMapPixelShader(SMapVertexToPixel PSIn)
{
SMapPixelToFrame Output = (SMapPixelToFrame)0;
Output.Color = PSIn.Position2D.z/PSIn.Position2D.w;
return Output;
}
technique ShadowMap
{
pass Pass0
{
VertexShader = compile vs_2_0 ShadowMapVertexShader();
PixelShader = compile ps_2_0 ShadowMapPixelShader();
}
}
ShadowedScene hlsl code
struct SSceneVertexToPixel
{
float4 Position : POSITION;
float4 Pos2DAsSeenByLight : TEXCOORD0;
float2 TexCoords : TEXCOORD1;
float3 Normal : TEXCOORD2;
float4 Position3D : TEXCOORD3;
};
struct SScenePixelToFrame
{
float4 Color : COLOR0;
};
float DotProduct(float3 lightPos, float3 pos3D, float3 normal)
{
float3 lightDir = normalize(pos3D - lightPos);
return dot(-lightDir, normal);
}
SSceneVertexToPixel ShadowedSceneVertexShader( float4 inPos : POSITION, float2 inTexCoords : TEXCOORD0, float3 inNormal : NORMAL)
{
SSceneVertexToPixel Output = (SSceneVertexToPixel)0;
Output.Position = mul(inPos, xWorldViewProjection);
Output.Pos2DAsSeenByLight = mul(inPos, xlightsWorld);
Output.Normal = normalize(mul(inNormal, (float3x3)xWorld));
Output.Position3D = mul(inPos, xWorld);
Output.TexCoords = inTexCoords;
return Output;
}
SScenePixelToFrame ShadowedScenePixelShader(SSceneVertexToPixel PSIn)
{
SScenePixelToFrame Output = (SScenePixelToFrame)0;
float2 ProjectedTexCoords;
ProjectedTexCoords[0] = PSIn.Pos2DAsSeenByLight.x/PSIn.Pos2DAsSeenByLight.w/2.0f +0.5f;
ProjectedTexCoords[1] = -PSIn.Pos2DAsSeenByLight.y/PSIn.Pos2DAsSeenByLight.w/2.0f +0.5f;
float diffuseLightingFactor = 0;
if ((saturate(ProjectedTexCoords).x == ProjectedTexCoords.x) && (saturate(ProjectedTexCoords).y == ProjectedTexCoords.y))
{
float depthStoredInShadowMap = tex2D(ShadowMapSampler, ProjectedTexCoords).r;
float realDistance = PSIn.Pos2DAsSeenByLight.z/PSIn.Pos2DAsSeenByLight.w;
if ((realDistance - 100.0f/100.0f) <= depthStoredInShadowMap)
{
diffuseLightingFactor = DotProduct(xLightPosition, PSIn.Position3D, PSIn.Normal);
diffuseLightingFactor = saturate(diffuseLightingFactor);
diffuseLightingFactor *= xLightPower;
}
}
float4 baseColor = tex2D(TextureSampler, PSIn.TexCoords);
Output.Color = baseColor*(diffuseLightingFactor + xAmbient);
return Output;
}
technique ShadowedScene
{
pass Pass0
{
VertexShader = compile vs_2_0 ShadowedSceneVertexShader();
PixelShader = compile ps_2_0 ShadowedScenePixelShader();
}
}
game code in the draw method
device.SetRenderTarget(0, renderTarget);
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
DrawCity("ShadowMap");
device.SetRenderTarget(0, null);
shadowMap = renderTarget.GetTexture();
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);
DrawCity("ShadowedScene");
terrain draw method
private void DrawCity(string technique)
{
effect.CurrentTechnique = effect.Techniques[technique];
effect.Parameters["xTexture"].SetValue(sceneryTexture);
effect.Parameters["xWorld"].SetValue(Matrix.Identity);
effect.Parameters["xLightPower"].SetValue(lightPower);
effect.Parameters["xWorldViewProjection"].SetValue(Matrix.Identity * camera.viewMatrix * camera.projectionMatrix);
effect.Parameters["xLightPosition"].SetValue(position);
effect.Parameters["xAmbient"].SetValue(ambientPower);
effect.Parameters["xlightsWorld"].SetValue(lightsViewProjectionMatrix);
effect.Parameters["xShadowMap"].SetValue(shadowMap);
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.VertexDeclaration = new VertexDeclaration(device, VertexPositionNormalTexture.VertexElements);
device.Vertices[0].SetSource(cityVertexBuffer, 0, VertexPositionNormalTexture.SizeInBytes);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, cityVertexBuffer.SizeInBytes / 3);
pass.End();
}
effect.End();
Matrix car2Matrix = Matrix.CreateScale(1f) * Matrix.CreateRotationY(MathHelper.Pi * 5.0f / 8.0f) * Matrix.CreateTranslation(12, 0, -10);
DrawModel(carModel, carTextures, car2Matrix, technique);
}
car draw method
private void DrawModel(Model model, Texture2D[] textures, Matrix wMatrix, string technique)
{
Matrix[] modelTransforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(modelTransforms);
int i = 0;
foreach (ModelMesh mesh in model.Meshes)
{
foreach (Effect currentEffect in mesh.Effects)
{
Matrix worldMatrix = modelTransforms[mesh.ParentBone.Index] * wMatrix;
currentEffect.CurrentTechnique = effect.Techniques[technique];
currentEffect.Parameters["xWorldViewProjection"].SetValue(worldMatrix * camera.viewMatrix * camera.projectionMatrix);
currentEffect.Parameters["xTexture"].SetValue(textures[i++]);
currentEffect.Parameters["xWorld"].SetValue(worldMatrix);
currentEffect.Parameters["xLightPosition"].SetValue(position);
currentEffect.Parameters["xLightPower"].SetValue(lightPower);
currentEffect.Parameters["xAmbient"].SetValue(ambientPower);
currentEffect.Parameters["xlightsWorld"].SetValue(worldMatrix * lightsViewProjectionMatrix);
currentEffect.Parameters["xShadowMap"].SetValue(shadowMap);
}
mesh.Draw();
}
}
Thanks again