Jump to content
  • Advertisement
Sign in to follow this  

[D3D11] Depth buffer not effecting shadow outcome

This topic is 1100 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been attempting to implement shadow mapping on my terrain project for quite some time, unfortunately I've ran into a few issues along the way.  Recently I've noticed the main problem is the fact that my depth buffer, which I bind to a shader resource doesn't seem to have an effect.


I go through these steps:

  1. Create a shadow map depth render target, shader resource view, and a shadow map view port
  2. Pre shadow pass, set the render target to the shadow map depth view, set the viewport to the shadow viewport and clear the shadow map depth stencil
  3. Shadow pass, render terrain
  4. Main render pre pass, reset the render target and the viewport and clear the (non shadowmap) render target and depth stencil
  5. Main render pass, set the pixel shader resource view to the previously drawn shadow map, render the terrain and then unbind the shadow map from the pixel shader

To create the shadow map, I use a vertex shader and a null pixel shader, which only writes depth information to the shadow map from the point of view of the light.  I create the light like so:

mPosition       = XMFLOAT3(0.0f, 30.0f, 0.0f);
mProjMatrix     = XMMatrixOrthographicLH(75.0f, 75.0f, 1.0f, 1000.0f);

XMFLOAT3 la3    = XMFLOAT3(126.0f, 0.0f, 126.0f), up3 = XMFLOAT3(0.0f, 1.0f, 0.0f);
XMVECTOR eye    = XMLoadFloat3(&mPosition), la = XMLoadFloat3(&la3), up = XMLoadFloat3(&up3);

mViewMatrix     = XMMatrixLookAtLH(eye, la, up);
mViewProjMatrix = XMMatrixMultiply(mViewMatrix, mProjMatrix);

(la3 is values for the center of the map)



Looking at the object table in the graphics debugger, I can see the depth buffer from the viewpoint of the light:




But the final outcome doesn't produce any shadows, just lighting using normals (grey is out of range of the light source, as it is orthographic):




The pixel shader I use:

Texture2D shadowMap	: register(t0);
SamplerState SampleTypePoint : register(s0);

cbuffer SPerLightCB : register(b0)
	float4 ambientColour;
	float4 diffuseColour;

cbuffer SPerLightPosCB : register(b1)
	float3 lightPos;
	float padding;

struct PixelIn
	float4 Pos    : SV_POSITION;
	float4 WPos   : TEXCOORD0;
	float4 LPos   : TEXCOORD1;
	float3 Normal : NORMAL;

float4 main(PixelIn pin) : SV_Target
	//re-homogenize position after interpolation
	pin.LPos.xyz /= pin.LPos.w;

	//if position is not visible to the light - dont illuminate it
	//results in hard light frustum
	if (pin.LPos.x < -1.0f || pin.LPos.x > 1.0f ||
		pin.LPos.y < -1.0f || pin.LPos.y > 1.0f ||
		pin.LPos.z < 0.0f || pin.LPos.z > 1.0f)
		return ambientColour;

	//transform clip space coords to texture space coords (-1:1 to 0:1)	
	pin.LPos.x = pin.LPos.x / 2 + 0.5;
	pin.LPos.y = pin.LPos.y / -2 + 0.5;

	//sample shadow map - point sampler
	float shadowMapDepth = shadowMap.Sample(SampleTypePoint, pin.LPos.xy).r;

	//if clip space z value greater than shadow map value then pixel is in shadow
	if (shadowMapDepth < pin.LPos.z)
		return ambientColour;

	//calculate ilumination at fragment
	float3 L = normalize(lightPos - pin.WPos.xyz);
	float ndotl = dot(normalize(pin.Normal), L);
	return ambientColour + diffuseColour * ndotl;

This is just to show the individual lighting results.  Red is out of range, blue is normal lighting and there should be green for shadows:



I'm completely at a loss, as to my knowledge I've set everything up correctly.  Any help would be greatly appreciated, if you need to see any code, just ask and I'll post the relevant parts.  Thanks again.

Share this post

Link to post
Share on other sites

Not entirely sure if it will affect the end result, but have you tried accounting for the depth bias?

input.lpos.z -= shadowMapBias;

where shadowMapBias is usually the a scene dependent (And object dependent) float that accounts for the limited precision of the depthBuffer.



Edited by markypooch

Share this post

Link to post
Share on other sites

At this point the bias doesn't really matter.  I'm also only sampling the xy values of the LPos, so doing anything to the z component won't really do anything.  Thank you for replying though.  


I've run out of ideas and I'm honestly not sure what else I can try.

Edited by DHCThrive

Share this post

Link to post
Share on other sites

Well it turns out I wasn't out of ideas.  I checked the MSDN sample and noticed that the sampler they were using was a SampletComparisonState, rather than a SamplerState.  I was using a SamplerState, but it got me thinking.  I changed my debug build and noticed that the sampler in the pixel shader was silently failing.  Essentially I was using a comparison sampler with a non comparison sampler defined in the pixel shader.  So I redefined my sampler as (in the c++ side):


sd.MipLODBias = 0;
sd.MaxAnisotropy = 1;
sd.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
sd.BorderColor[0] = 0.0f;
sd.BorderColor[1] = 0.0f;
sd.BorderColor[2] = 0.0f;
sd.BorderColor[3] = 0.0f;
sd.MinLOD = 0.0f;
sd.MaxLOD = 0.0f;

So now I have shadows!  Time to get rid of the surface acne and make them better.



Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!