0
\$\begingroup\$

I've been following the tutorials listed below:

http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series3/Shadow_map.php

http://xbox.create.msdn.com/en-US/education/catalog/sample/shadow_mapping_1

And I made my shadow map creator effect:

float4x4 WorldViewProjection;

float4x4 LightingWorld;
float4x4 LightingViewProjection;

struct VertexToPixel {
    float4 Position : POSITION;
    float Depth : TEXCOORD0;
};

VertexToPixel ShadowMapVertexShader(float4 position : POSITION) {
    VertexToPixel output = (VertexToPixel)0;

    output.Position = mul(position, mul(LightingWorld, LightingViewProjection));
    output.Depth = output.Position.z / output.Position.w;

    return output;
}

float4 ShadowMapPixelShader(VertexToPixel input) : COLOR0 {
    float4 color = input.Depth;
    color.a = 1;

    return color;
}

I use the following flashlight (which has a cone angle: coneAngleHalfRad * 2) View and Projection matrices for the shadow map (and for checking the depths later):

        lightProjection = Matrix.CreatePerspectiveFieldOfView(
            coneAngleHalfRad * 2, 
            1, 
            1, //0.25f, 
            range);

        //Helper.Message(this, "draw shadow maps: " + needsShadows);
        //Helper.Message(this, "rotation up: " + rotation.Up);
        lightView = Matrix.CreateLookAt(position, position + (direction * range), rotation.Up);
        lightViewProjection = lightView * lightProjection;
        DepthMapMakerEffect.Parameters["LightingWorld"].SetValue(Matrix.Identity);
        DepthMapMakerEffect.Parameters["LightingViewProjection"].SetValue(lightViewProjection);
        DepthMapMakerEffect.Techniques[0].Passes[0].Apply();

        device.SetRenderTarget(RenderDirectional);
        device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);

        drawAction(this, DepthMapMakerEffect);

        device.SetRenderTarget(null);
        ShadowMapDirectional = (Texture2D)RenderDirectional;

I set my shadow map to the effect:

TextureManager.DynamicTexturingEffect.Parameters["Flashlight" + numFlashlightsPP + "Map"].SetValue(((Flashlight)lights[lightIndex]).ShadowMapDirectional);

And when I am drawing the light with additive blend state, I use the following code to get the depths from the shadow map and from the camera (is it from the camera? I didn't understand yet):

shared float DepthBias = 0.001f;

//  [...]

shared Texture Flashlight0Map;
shared sampler Flashlight0MapSampler = sampler_state { 
    texture = <Flashlight0Map>; 
    magfilter = LINEAR; 
    minfilter = LINEAR; 
    mipfilter = LINEAR; 
    AddressU = clamp; 
    AddressV = clamp;
};

//  [...]

//  Find the position of this pixel in light space.
float4 lightingPosition = mul(worldPosition, flashlight.LightingViewProjection);

//  Find the position in the shadow map for this pixel.
float2 shadowTexCoord = 0.5 * lightingPosition.xy / 
                        lightingPosition.w + float2(0.5, 0.5);
shadowTexCoord.y = 1.0f - shadowTexCoord.y;

//  Get the current depth stored in the shadow map.
float shadowDepth = tex2D(Flashlight0MapSampler, shadowTexCoord).r;  

//  Calculate the current pixel depth.
// The bias is used to prevent folating point errors that occur when
// the pixel of the occluder is being drawn.
float ourDepth = (lightingPosition.z / lightingPosition.w) - DepthBias;

//  [...]

float intensity = 0; 
if (ourDepth <= shadowDepth) {
    if (atten > 0) {
        intensity = saturate((flashlight.Range - dist) / flashlight.Range) * (dot(vertexNormal, perVertexNormal) * fog) * atten;
    }
}

But what happens is that the result is ALWAYS "ourDepth > shadowDepth", which makes the entire light always hidden so it's always shadowed no matter if there's an object in front of it or not.

What could I possible be doing wrong? I think I used wrong values in the flashlight's View and Projection. But I can't find the error. What might be the problem?

Any suggestion may help!

EDIT: I'm not using the same aspect ratio of the screen and of the camera for the shadow map. Do I need to?

\$\endgroup\$
1
\$\begingroup\$

So, I found out I was multiplying the positions by an empty World matrix somewhere in the effect file, and the values went wrong or null.

I'm not sure about what really happened, but that was one of the causes. 'Cause it started working after cleaning the code of unused variables.

I had to adjust DepthBias to 0.01f too. Oh, and I had to multiply the Input Position by the World Matrix in the Vertex Shader to get the World Position and not in the Pixel Shader as I was doing before.

EDIT: I had to clean my shadow map renderer to black, too, and not to white.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.