Hi folks,
I'm running in to trouble trying to get my deferred light maps working for directional lights.
In my light map pass I render all of the geometry in the scene using a world/view/projection matrix based on the position and direction of the light source. The result I'm getting looks like what I'd expect it to be.
Trouble comes in (I'm assuming) the pixel shader when I'm try to convert the current world position in to light-screen-space. I'd really appreciate it if you could run your eyes over the logic...
So the setup for the light matrix that I pass in to the pixel shader's constant buffer :
// Calculate the world/view/projection matrix for the light
XMMATRIX world = XMLoadFloat4x4( &aCamera->GetWorld() );
XMMATRIX view = XMMatrixLookAtLH( XMLoadFloat3(&aLight->GetPosition()), XMLoadFloat3(&lightDirection), XMLoadFloat3(&XMFLOAT3(0.0f, 1.0f, 0.0f)) );
XMMATRIX projection = XMMatrixPerspectiveFovLH( XMConvertToRadians(30.0f), 1.0f, 1.0f, 1024.0f );
XMMATRIX lightWVP = XMMatrixMultiply( XMMatrixMultiply(world, view), projection );
// Bind the matrix to the lighting buffer
lightingBuffer->myLightViewProjection = XMMatrixTranspose( lightWVP );
Then in the shader I calculate the world space position (currentDepth is sampled from the depth g-buffer):
// Calculate the screen-space position
float4 currentPosition;
currentPosition.x = anInput.myTexCoords.x * 2.0f - 1.0f;
currentPosition.y = -(anInput.myTexCoords.y * 2.0f - 1.0f);
currentPosition.z = currentDepth;
currentPosition.w = 1.0f;
// Transform the screen space position in to world-space
currentPosition = mul( currentPosition, myInverseViewProjection );
currentPosition /= currentPosition.w;
And then I convert the current position in to light-space :
// multiply current position by light view projection to get light-screen space
float4 lightScreenPosition = mul( currentPosition, myLightViewProjection );
// convert position in to texture coordinates
float2 lightTextureCoords = 0.5f * (float2(lightScreenPosition.x, -lightScreenPosition.y) + 1);
// sample from light depth map
float lightDepth = ShadowMap.Sample( ShadowSampler, lightTextureCoords ).r;
And I guess if the lightDepth > currentDepth then I should be returning my ambient light for the current pixel?
if( lightDepth > currentDepth )
{
return float4( 0.1f, 0.1f, 0.1f, 0.1f );
}
// otherwise continue on with the light map calculations
I'm obviously messing something up here, any ideas what?
Thanks for your help!