PCF Filtering doesnt work quite well

Started by
1 comment, last by MJP 3 years, 10 months ago

Hi, I have enabled pcf filtering in my shader yet it doesnt work well. I dont get soft shadows. How can I address this issue?


float2 offset(int u, int v, float sm_size)
{
    return float2(u * (1.0f / sm_size), v * (1.0f / sm_size));
}

float SampleDepthMap(Texture2D texArr[3], int index, float2 coord, float lightDepthValue)
{
	float ret = 0;
    if(index == 0)
    {
		for (float y = -1.5; y <= 1.5; y += 1.0)
		{
			for (float x = -1.5; x <= 1.5; x += 1.0)
			{
				ret += texArr[0].SampleCmpLevelZero(ssModelCSM, coord + offset(x, y, 4096), lightDepthValue);
			}
		}

    }
    else if(index == 1)
    {
		for (float y = -1.5; y <= 1.5; y += 1.0)
		{
			for (float x = -1.5; x <= 1.5; x += 1.0)
			{
				ret += texArr[1].SampleCmpLevelZero(ssModelCSM, coord + offset(x, y, 2048), lightDepthValue);
			}
		}
    }
	else if (index == 2)
	{
		for (float y = -1.5; y <= 1.5; y += 1.0)
		{
			for (float x = -1.5; x <= 1.5; x += 1.0)
			{
				ret += texArr[2].SampleCmpLevelZero(ssModelCSM, coord + offset(x, y, 2048), lightDepthValue);
			}
		}
	}
	ret /= 16.0f;

	return ret;
}
Advertisement

It's hard to tell just from one screen shot, but based on the code you provided your filtering kernel has a fixed size in shadow map space. The nature of shadow maps is that the effective size of a shadow map texel in screen space completely depends on how the shadow itself ends up getting projected into screen space. If you put the camera up next to the shadow you should see the filtering more clearly. The filtering should also be more noticeable if you change the shadow projection so that it covers more area in world space, and/or lower the shadow map resolution.

Some other notes:

  1. You really don't want to branch on the shadow map index like that, you should use a Texture2DArray
  2. For a high-quality PCF kernel you don't want to use uniform sample weights like that. You really want to compute the fractional coverage of a PCF kernel centered around the pixel position, which won't be aligned to shadow map texels (see the section on “Edge Tap Smoothing” in this presentation). I have some code here that does an arbitary-sized kernel, but you probably want to use one of the optimized variants in that same file that make use of HW bilinear filtering or GatherCmp.

This topic is closed to new replies.

Advertisement