Jump to content
  • Advertisement
Sign in to follow this  
cozzie

Understanding the shadow matrix

This topic is 1076 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

Hi all,

While learning d3d11, I've come to the topic 'shadowing'.

To make sure I understand the theory, I've written out the explanation below.

 

My question:

- do you think I'm on the right track/ do I understand it correctly?

(I'd like to be sure and not just assume and go on with the code I have)

 

Thanks in advance.

 

shadowmatrix.jpg

Share this post


Link to post
Share on other sites
Advertisement

What shadowing method are you shooting for? Mapping, volumes, cascading ect...

 

Edit: Basically each pixel needs to be transformed to be viewed from the angle of the light. If the pixel depth is closer than the transformed depth, the pixel is in the dark, if they are the same, it is lit

Edited by ExErvus

Share this post


Link to post
Share on other sites

Here an explanation of shadow mapping :

1) You generate a distance map from the light position, it's called shadow map, it's like depth map but for the light and not the camera.

2) You compare in the pixel shader the shadow map with the distance of the pixel in light space, this is the distance of the pixel view from the light.

    If the distance of the pixel in light space is upper than the value from the shadow map, that mean the point is behind something.

    If the point is behind something that mean the pixel is in shadow.

 

For the compare, you have to use an epsilon value because of floating point precision.

Here a the HLSL shader code for hard shadow (shadow without filtering) :

float ComputHardShadowFactor(in SURFACE_DATA SurfaceData)
{ 
  // Transform world space to light space.
  float4 PositionLightCS = mul(SurfaceData.PositionW, SunViewProj);
  
  // Light depth in NDC space.
  float LightDepth = PositionLightCS.z - 0.006f;
  
  // Transform from NDC space to texture space.
  float2 ShadowTexCoord = 0.5f * float2(PositionLightCS.x, -PositionLightCS.y) + 0.5f;
  
  // Shadow depth test.
  float ShadowMapSample = SunShadowMap.SampleLevel(ShadowSampler, ShadowTexCoord, 0).r;
  return LightDepth <= ShadowMapSample;
}

Here the lighting calcule :

Light.Intensity * Light.Color * (SurfaceData.DiffuseColor * NdotL + SpecFactor) * ShadowFactor;
Edited by Alundra

Share this post


Link to post
Share on other sites
Thanks, this clears things up.
Combined with the shadow theory and matrix from my d3d11 (luna) book, I should be able to figure things out.

Share this post


Link to post
Share on other sites

Luna book uses 3x3 averaging algorithm to filter the shadow :

float percentLit = 0.0f;

const float2 offsets[9] = 
{
  float2(-dx,  -dx), float2(0.0f,  -dx), float2(dx,  -dx),
  float2(-dx, 0.0f), float2(0.0f, 0.0f), float2(dx, 0.0f),
  float2(-dx,  +dx), float2(0.0f,  +dx), float2(dx,  +dx)
};

[unroll]
for(int i = 0; i < 9; ++i)
{
  percentLit += shadowMap.SampleCmpLevelZero(samShadow, 
  shadowPosH.xy + offsets[i], depth).r;
}

return percentLit /= 9.0f;

You can do the hardware PCF using a SamplerComparisonState :

D3D11_SAMPLER_DESC ShadowSamplerDesc;
ShadowSamplerDesc.Filter           = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
ShadowSamplerDesc.AddressU         = D3D11_TEXTURE_ADDRESS_BORDER;
ShadowSamplerDesc.AddressV         = D3D11_TEXTURE_ADDRESS_BORDER;
ShadowSamplerDesc.AddressW         = D3D11_TEXTURE_ADDRESS_BORDER;
ShadowSamplerDesc.MipLODBias       = 0.0f;
ShadowSamplerDesc.MaxAnisotropy    = 1;
ShadowSamplerDesc.ComparisonFunc   = D3D11_COMPARISON_LESS_EQUAL;
ShadowSamplerDesc.BorderColor[ 0 ] = 0.0f;
ShadowSamplerDesc.BorderColor[ 1 ] = 0.0f;
ShadowSamplerDesc.BorderColor[ 2 ] = 0.0f;
ShadowSamplerDesc.BorderColor[ 3 ] = 0.0f;
ShadowSamplerDesc.MinLOD           = 0.0f;
ShadowSamplerDesc.MaxLOD           = D3D11_FLOAT32_MAX;

In the shader :

ShadowMap.SampleCmpLevelZero(ShadowSampler, uv, LightDepth);
Edited by Alundra

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!