Shadow Mapping Depth Buffer

Started by
1 comment, last by Irlan Robson 9 years, 5 months ago

I am trying to implement the Shadow Mapping Technique using DirectX 11.

The Light Depth Buffer is the first pass and the camera is the second. In the first pass I write only the depth information with this vertex shader:


cbuffer CB_PER_INSTANCE : register(b0) {
float4x4 mWorld;
float4x4 mCamView;
float4x4 mCamProj;
float4x4 mNormal;
float4x4 mLightView;
float4x4 mLightProj;
};

void main(in float3 _vLocalPos : POSITION0, out float4 _vOutPos : SV_POSITION) {
_vOutPos = mul(mWorld, float4(_vLocalPos, 1.0f));
_vOutPos = mul(mLightView, _vOutPos);
_vOutPos = mul(mLightProj, _vOutPos);
}

In the second pass, I render normally my scene using two shaders:


struct VS_IN {
float3 vLocalPos : POSITION0;
//There is other members here.
};


struct PER_INSTANCE_DATA {
float4x4 mWorld;
float4x4 mCamView;
float4x4 mCamProj;
float4x4 mNormal;
float4x4 mLightView;
float4x4 mLightProj;
};


cbuffer CB_PER_INSTANCE : register(cb0) {
PER_INSTANCE_DATA pidPerInstance;
};

struct VS_OUT {
float4 vViewPos : TEXCOORD0;
float3 vViewNormal : TEXCOORD1;
float2 vTexCoord : TEXCOORD2;
float4 vLightProjPos : TEXCOORD3;
};

void main(in VS_IN _viIn, out VS_OUT _voOut, out float4 _vOutPos : SV_POSITION) {
float4 vWorldPos = mul( pidPerInstance.mWorld, float4(_viIn.vLocalPos, 1.0f) );

//Camera Space.
_voOut.vViewPos = mul(pidPerInstance.mCamView, vWorldPos);
_vOutPos = mul(pidPerInstance.mCamProj, _voOut.vViewPos);

_voOut.vViewNormal = mul( (float3x3)(pidPerInstance.mNormal), _viIn.vLocalNormal );
_voOut.vTexCoord = _viIn.vLocalTexCoord;

//Light Space.
_voOut.vLightProjPos = mul(pidPerInstance.mLightView, vWorldPos);
_voOut.vLightProjPos = mul(pidPerInstance.mLightProj, _voOut.vLightProjPos);
}

struct VS_OUT {
float4 vViewPos : TEXCOORD0;
float3 vViewNormal : TEXCOORD1;
float2 vTexCoord : TEXCOORD2;
float4 vLightProjPos : TEXCOORD3;
};

Texture2D t2dDepthMap : register(t0);
SamplerState ssShadowSampler : register(s0) {
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};

void main(in VS_OUT _voOut, out float4 _vOutColor : SV_TARGET) {

float2 vLightProjTexCoord = _voOut.vLightProjPos.xy / _voOut.vLightProjPos.w;
vLightProjTexCoord.x = ( vLightProjTexCoord.x / 2.0f ) + 0.5f;
vLightProjTexCoord.y = ( vLightProjTexCoord.y / 2.0f ) - 0.5f;
float fThisDepthFromLight = _voOut.vLightProjPos.z / _voOut.vLightProjPos.w;

float fShadowMapPixelDepth = t2dDepthMap.Sample(ssShadowSampler, vLightProjTexCoord).r;

if ( fThisDepthFromLight > fShadowMapPixelDepth ) {
_vOutColor = float4(0.0f, 0.0f, 0.0f, 1.0f);
}
else {
_vOutColor = float4(1.0f, 0.0f, 0.0f, 1.0f);
}
}

I use Intel GFA to debug one piece of frame. Here's the results:

Camera Z-Buffer:

Actually this doesn't matter since the technique uses only Light Projection for computations.

camz.jpg

Light Z-Buffer:

lightz.jpg

What I got:

camcolors.jpg

The Light is at (0.0, 0.0, 0.0) looking at (0.0, 0.0, 1.0) and uses a Perspective Projection. The last one was just an example of the final colors, but when I navigate to another point of view nothing happens, all I got is black colors.

I'm using the Debug Interface also, and everything is correct.

Advertisement

but when I navigate to another point of view nothing happens, all I got is black colors.

Are you saying the results are correct at a particular camera position/direction? If so, can you move the camera a very small amount and still get non-black colors?

Your shader code looks generally correct. However, you should be testing that the object position is within view of the light, otherwise the depth sample will not be correct. I.e., if it is not in view of the light, illuminate it. I.e.,


// Determine if the projected coordinates are in the 0 to 1 range.  If so then this pixel is in the view of the light.
if( (saturate(vLightProjTexCoord.x) == vLightProjTexCoord.x) && (saturate(vLightProjTexCoord.y) == vLightProjTexCoord.y) )
{
   // do your depthvalue calcs
}
else // not in the light's view volume, illuminate it
   vOutColor = float4(1.0f, 0.0f, 0.0f, 1.0f);

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I solved my problem. My projected texture coordinates was incorrect. The correct is:


vProjTexCoord.y = (vProjTexCoord.y * -0.5f) + 0.5f;

I was checking the Lighting Volume in HDC coordinates. Eg.:


if ( vLightPos.x >= -1.0f || ...etc. )

Also, I wasn't creating a Sampler. Since I'm not using the Effects Framework, had to set it manually.

Thank you.

This topic is closed to new replies.

Advertisement