PCF in cubemap

Started by
9 comments, last by widmowyfox 8 years, 3 months ago

I have question about PCF filtering on cubemap . So how can I implement 3x3 PCF in cubemap, am i doing it already(PCF) using SampleCmpLevelZero (as in 2d textures)? It looks like no PCF.

Shadow factor code:



float3 l=cam;
float3 pos=shadowPosH-l;
float dis=length(pos);
float3 dir=normalize(pos);
float projectedDistance = max(max(abs(pos.x), abs(pos.y)), abs(pos.z));
float a = shadowproj._33;
float b = shadowproj._43;
float z = projectedDistance * a + b;
float dbDistance = z / projectedDistance;

	float percentLit = 0.0f;



	
		return shadowMap.SampleCmpLevelZero(samShadow,dir,dbDistance).r;
Sampler:
SamplerComparisonState samShadow
{
	Filter   = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
	AddressU = BORDER;
	AddressV = BORDER;
	AddressW = BORDER;
	BorderColor = float4(0.0f, 0.0f, 0.0f, 0.0f);

    ComparisonFunc = LESS_EQUAL;
};
 

Sampler:


SamplerComparisonState samShadow
{
    Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
    AddressU = BORDER;
    AddressV = BORDER;
    AddressW = BORDER;
    BorderColor = float4(0.0f, 0.0f, 0.0f, 0.0f);

ComparisonFunc = LESS_EQUAL;
};

Advertisement

So how can I implement 3x3 PCF in cubemap

By using a single 2D texture for your cubemap with all 6 faces in it and filtering that in the standard way. Expand on the rendering area of each face in order to sample “neighboring” faces.

It looks like no PCF.

You are only sampling 1 time. That is by-definition not PCF (unless you are using hardware support).


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Maybe you'll find this helpful? http://www.sunandblackcat.com/tipFullView.php?l=eng&topicid=36

.:vinterberg:.

I tried this (below), but it is not working, why?

dx=1.0/mapsize


float3 gridSamplingDisk[20] ={

float3(dx, dx, dx), float3(dx, -dx, dx), float3(-dx, -dx, dx), float3(-dx, dx, dx),
float3(dx, dx, -dx), float3(dx, -dx, -dx), float3(-dx, -dx, -dx), float3(-dx, dx, -dx),
float3(dx, dx, 0), float3(dx, -dx, 0), float3(-dx, -dx, 0), float3(-dx, dx, 0),
float3(dx, 0, dx), float3(-dx, 0, dx), float3(dx, 0, -dx), float3(-dx, 0, -dx),
float3(0, dx, dx), float3(0, -dx, dx), float3(0, -dx, -dx), float3(0, dx, -dx)
};
[unroll]
for(int i=0;i<20;i++){

	
		percentLit+= shadowMap.SampleCmpLevelZero(samShadow, 
			dir+gridSamplingDisk[i],dbDistance).r;
	
	}
return percentLit/=20.0f;

Why don’t you explain how it doesn’t work? Doesn’t compile? Doesn’t display correctly? Displays nothing? Displays the same as the old version? Could you provide important details when asking questions?
Why don’t you debug it for yourself? If you can’t use a debugger then you can’t program. How are we supposed to help if you haven’t gone through with a graphical debugger and verified the correctness of the values in your code? Is dx correct? If you had used a debugger and found the dx was set to 0, you would already have been able to solve the problem on your own.

If you had verified that dx was correct, why didn’t you include that information in your post?

Also your code is extremely slow compared to the code you copied. Why didn’t you do it how he showed in his tutorial? The values should be [1,1,1], [1,-1,1], etc. with a multiply in the loop. Why did you deviate from that? With your version you have to spend tons of shader time creating gridSamplingDisk with no performance gain inside the loop.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

It does not work- shadows are still hard, i cant use value like 1 or -1 because i am using sampleCmpLevelZero, these values are simply too big and when i tried this there werent any shadows on scene. And I was writed that dx=1.0/mapsize What can I do to improve final result?

Now shadows look like this:

vn2e6e.jpg

Have you tried that code with different values of dx?

It works for bigger dx for example 1/1000 but ...screen (lines on floor). What is the reason?

2jenx50.jpg

That's shadow acne, a typical artifact. Your bias is too small. Increasing it has other downsides though: Welcome to the pain of shadowmapping wink.png

Edit: Hmmm, do you not render front face culled to your shadow map ? Looks like self-shadowing of that plane.

gridSamplingDisk[] array should look like this:


const static float3 gridSamplingDisk[20] = {
	{ 1, 1, 1}, { 1,-1, 1}, {-1,-1, 1}, {-1, 1, 1},
	{ 1, 1,-1}, { 1,-1,-1}, {-1,-1,-1}, {-1, 1,-1},
	{ 1, 1, 0}, { 1,-1, 0}, {-1,-1, 0}, {-1, 1, 0},
	{ 1, 0, 1}, {-1, 0, 1}, { 1, 0,-1}, {-1, 0,-1},
	{ 0, 1, 1}, { 0,-1, 1}, { 0,-1,-1}, { 0, 1,-1},
};

From my own shader:


		float3 uvw = -lightdir;
		for (int i = 0; i < 20; i++)
		{
			float3 tuv = uvw + fShadowFilter[i] * vSizes.w;              // vSizes.w = 1.0f / TextureSize
			shadow += tShadowmapTexture.SampleCmpLevelZero(ShadowmapTextureSampler, tuv, basis);
		}
		shadow = saturate(shadow * 0.05);  // 1.0/20.0 = 0.05

You need to add/subtract a small bias to your dbDistance, you can read about it here: http://www.sunandblackcat.com/tipFullView.php?l=eng&topicid=35 ("Additional offset to depth values in shadow map" section)

.:vinterberg:.

This topic is closed to new replies.

Advertisement