Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I implemented planar shadows with the function D3DXMatrixShadow.

As you know, we need plane and light factor to calculate a shadow matrix.

The problem is that when I set the plane as D3DXPLANE p(0, -1, 0, 0.1f), the shadows by directional light are correctly rendered, but the shadows by point light are not rendered.

However, if I use D3DXPLANE p(0, 1, 0, 0.1f), the situation is reversed, shadows by directional light are not drawn, the shadows by point light are ok.

I cannot understand why it happens. Is it normal or am i missing something? Please explain to me why this happens.

Thanks in advance.

Code

//main.cpp 
ID3D10EffectTechnique* oldTech = meshes[i]->technique;

D3DXPLANE groundPlane(0, -1, 0, 0.01f);
D3DXMATRIX S;//shadow matrix
D3DXVECTOR4 light;
if(lightType != 2) //2 here means point light
{
    light.x = lightDirection.x;
    light.y = lightDirection.y;
    light.z = lightDirection.z;
    light.w = 0;
}
else
{
    light.x = lightPosition.x;
    light.y = lightPosition.y;
    light.z = lightPosition.z;
    light.w = 1;
    groundPlane.b = 1;
}

D3DXMatrixShadow(&S, &light, &groundPlane);
D3DXMATRIX W = meshes[i]->GetWorldMatrix();
D3DXMATRIX matWorld = W * S;

meshes[i]->technique = shadowTechnique;
meshes[i]->render(&matWorld); 
//Meshes here are drawn by ID3DX10Mesh, 
//but I tested other code with LPD3DXMESH, it has the same problem. 

meshes[i]->technique = oldTech;

 //shader code(.fx file)
 PS_Input VS_Shadow(VS_Input input)
 {
    PS_Input output = (PS_Input)0;
    output.pos = mul(float4(input.pos, 1), matWorld);
    output.pos.y = 0.1;
    output.pos = mul(mul(output.pos, matView), matProjection);
    output.normal = mul( input.normal, (float3x3)matWorld );
    output.color = input.color;
    output.worldPos = (float3)mul(input.pos, matWorld);
    output.tex = input.tex; 
    return output;
 }

 float4 PS_Shadow( PS_Input input) : SV_Target
 {
    return float4(0,0,0,0.5f);
 }

 DepthStencilState StencilIncreaseOnce {
    DepthEnable = true;
    DepthWriteMask = ALL;
    DepthFunc = LESS_EQUAL;

    StencilEnable = true;
    FrontFaceStencilFunc = EQUAL;
        FrontFaceStencilPass = INCR;
    FrontFaceStencilFail = Keep;
 };

 BlendState BlendAlpha {
    AlphaToCoverageEnable = FALSE;
    BlendEnable[0] = TRUE;
    SrcBlend = SRC_ALPHA ;
    DestBlend = INV_SRC_ALPHA ;
    BlendOp = ADD;
    SrcBlendAlpha = ONE;
    DestBlendAlpha = ZERO;
    BlendOpAlpha = ADD;
    RenderTargetWriteMask[0] = 0x0F;
 };

 technique10 ShadowRender
 {
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS_Shadow() ) );
        //SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS_Shadow() ) );     

        SetDepthStencilState( StencilIncreaseOnce, 0x0 );
        SetBlendState( BlendAlpha, float4( 0.0f, 0.0f, 0.0f, 0.0f ),
                   0xFFFFFFFF ); //blendState, blendFactor, sampleMask
    }
 }
share|improve this question
    
Can you post the relevant parts of your code? Such as how you set up the light positions, calculate the shadow matrix, and render the shadows? –  Nathan Reed Nov 19 '11 at 4:53
    
@NathanReed I added my code. –  DevExcite Nov 19 '11 at 9:02

1 Answer 1

up vote 0 down vote accepted

Your code looks mostly correct to me. One thing that's a little weird is the output.pos.y = 0.1; in your VS. The reason this concerns me is that when you're using a point light, the shadow matrix is a projection matrix, and that means that after going through it your points are going to come out with w != 1.0. So you can't just set y to 0.1 to make them come out at y = 0.1...you'd have to set y to w * 0.1.

Another thing that might be an issue is a possible mismatch in the convention of lightDirection. I believe the function expects a vector pointing toward the light, but some people prefer to define it in terms of the direction the light is traveling, which the opposite. But if this was the probem I'd expect to see the shadows appearing to the lit side of the object instead of the shadowed side, since the whole vector would be negated and not just the y component.

share|improve this answer
    
I think your second paragraph contains the answer. We use the lightDirection as the direction of the light, not the opposite. I think that made the difference. Thank you! –  DevExcite Nov 20 '11 at 7:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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