how to define a field of view for the entire map for shadow?

Posted by Mehdi Bugnard on Game Development See other posts from Game Development or by Mehdi Bugnard
Published on 2014-08-22T08:48:45Z Indexed on 2014/08/22 10:28 UTC
Read the original article Hit count: 344

Filed under:
|
|
|
|

I recently added "Shadow Mapping" in my XNA games to include shadows. I followed the nice and famous tutorial from "Riemers" : http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series3/Shadow_map.php .

This code work nice and I can see my source of light and shadow. But the problem is that my light source does not match the field of view that I created. I want the light covers the entire map of my game. I don't know why , but the light only affect 2-3 cubes of my map.

ScreenShot: (the emission of light illuminates only 2-3 blocks and not the full map) enter image description here

Here is my code i create the fieldOfView for LightviewProjection Matrix:

Vector3 lightDir = new Vector3(10, 52, 10);
lightPos = new Vector3(10, 52, 10);
Matrix lightsView = Matrix.CreateLookAt(lightPos, new Vector3(105, 50, 105), new Vector3(0, 1, 0));
Matrix lightsProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver2, 1f, 20f, 1000f);
lightsViewProjectionMatrix = lightsView * lightsProjection;

As you can see , my nearPlane and FarPlane are set to 20f and 100f . So i don't know why the light stop after 2 cubes. it's should be bigger

Here is set the value to my custom effect HLSL in the shader file

    /* SHADOW VALUE */

    effectWorld.Parameters["LightDirection"].SetValue(lightDir);
    effectWorld.Parameters["xLightsWorldViewProjection"].SetValue(Matrix.Identity * .lightsViewProjectionMatrix);
    effectWorld.Parameters["xWorldViewProjection"].SetValue(Matrix.Identity * arcadia.camera.View * arcadia.camera.Projection);
    effectWorld.Parameters["xLightPower"].SetValue(1f);
    effectWorld.Parameters["xAmbient"].SetValue(0.3f);

Here is my custom HLSL shader effect file "*.fx"

    // This sample uses a simple Lambert lighting model.
float3 LightDirection = normalize(float3(-1, -1, -1));
float3 DiffuseLight = 1.25;
float3 AmbientLight = 0.25;
uniform const float3    DiffuseColor = 1;
uniform const float     Alpha = 1;
uniform const float3    EmissiveColor  = 0;
uniform const float3    SpecularColor = 1;
uniform const float     SpecularPower = 16;
uniform const float3    EyePosition;
// FOG attribut
uniform const float     FogEnabled  ;
uniform const float     FogStart ;
uniform const float     FogEnd ;
uniform const float3    FogColor ;
float3 cameraPos : CAMERAPOS;

texture Texture;

sampler Sampler = sampler_state
{
    Texture = (Texture);
    magfilter = LINEAR; 
    minfilter = LINEAR; 
    mipfilter = LINEAR; 
    AddressU = mirror; 
    AddressV = mirror;

};
texture xShadowMap;
sampler ShadowMapSampler = sampler_state 
{ 
    Texture = <xShadowMap>; 
    magfilter = LINEAR; 
    minfilter = LINEAR; 
    mipfilter = LINEAR; 
    AddressU = clamp; 
    AddressV = clamp; 
};

/* *************** */
/* SHADOW MAP CODE */
/* *************** */
struct SMapVertexToPixel
{
    float4 Position     : POSITION;
    float4 Position2D    : TEXCOORD0;
};

struct SMapPixelToFrame
{
    float4 Color : COLOR0;
};
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, xLightsWorldViewProjection);
    Output.Normal = normalize(mul(inNormal, (float3x3)World));
    Output.Position3D = mul(inPos, World);
    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 - 1.0f / 100.0f) <= depthStoredInShadowMap)
        {
            diffuseLightingFactor = DotProduct(xLightPos, PSIn.Position3D, PSIn.Normal);
            diffuseLightingFactor = saturate(diffuseLightingFactor);
            diffuseLightingFactor *= xLightPower;
        }
    }

    float4 baseColor = tex2D(Sampler, PSIn.TexCoords);
        Output.Color = baseColor*(diffuseLightingFactor + xAmbient);

    return Output;
}

SMapVertexToPixel ShadowMapVertexShader(float4 inPos : POSITION)
{
    SMapVertexToPixel Output = (SMapVertexToPixel)0;

    Output.Position = mul(inPos, xLightsWorldViewProjection);
    Output.Position2D = Output.Position;

    return Output;
}

SMapPixelToFrame ShadowMapPixelShader(SMapVertexToPixel PSIn)
{
    SMapPixelToFrame Output = (SMapPixelToFrame)0;

    Output.Color = PSIn.Position2D.z / PSIn.Position2D.w;

    return Output;
}

/* ******************* */
/* END SHADOW MAP CODE */
/* ******************* */

/ For rendering without instancing.
technique ShadowMap
{

    pass Pass0
    {
        VertexShader = compile vs_2_0 ShadowMapVertexShader();
        PixelShader = compile ps_2_0 ShadowMapPixelShader();

    }
}

technique ShadowedScene
{
    /*
    pass Pass0
    {
        VertexShader = compile vs_2_0 VSBasicTx();
        PixelShader = compile ps_2_0 PSBasicTx();
    }
    */
    pass Pass1
    {
        VertexShader = compile vs_2_0 ShadowedSceneVertexShader();
        PixelShader = compile ps_2_0 ShadowedScenePixelShader();
    }

}
technique SimpleFog
{
    pass Pass0
    {
        VertexShader = compile vs_2_0 VSBasicTx();
        PixelShader = compile ps_2_0 PSBasicTx();
    }
}

I edited my fx file , for show you only information and functions about the shadow ;-)

© Game Development or respective owner

Related posts about XNA

Related posts about lighting