Hi
I have implemented hardware PCF for a demo application. On Nvidia GPU's the approach is pretty straight forward. I use the z-buffer as a texture and sample it with tex2Dproj, then the PCF is carried out automatically. On Ati hardware the case was a little bit trickier. I had to use the fetch4 functionality and emulate bilinear interpolation between the four samples in the shader. My code look like this:
The problem is that the visual result is not the same on both vendors. Even though the artefacts on Ati is not too severe, Nvidia looks much better. See the comparison pictures bellow.
As you can see the shadows is not identical and Ati hardware got black and white stripes running through the penumbra of the shadows.
I don't know the reason for this problem or if it can be fixed. I found the order in which the four samples from fetch4 operation is interpolated by trial&error. Am I doing it right? Also I tried to add a small bias to float2( SHADOW_BUFFER_WIDTH, SHADOW_BUFFER_HEIGHT) and the the artefacts became severer. Which indicate that there might be some numerical instability bug somehow? I don't know. If someone could explain what's going wrong I would be really happy.
Thanks
I have implemented hardware PCF for a demo application. On Nvidia GPU's the approach is pretty straight forward. I use the z-buffer as a texture and sample it with tex2Dproj, then the PCF is carried out automatically. On Ati hardware the case was a little bit trickier. I had to use the fetch4 functionality and emulate bilinear interpolation between the four samples in the shader. My code look like this:
Code:
// Application code
V( pd3dDevice->CreateTexture( SHADOW_BUFFER_WIDTH, SHADOW_BUFFER_HEIGHT, 1, D3DUSAGE_DEPTHSTENCIL, (D3DFORMAT)(MAKEFOURCC('D','F','2','4')),
D3DPOOL_DEFAULT, &g_pShadowTexture, NULL));
V( pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T','4')));
V( pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT));
V( pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT));
// Shader code
float4 vecNormCoord = In.LightSpacePos.xyzw / In.LightSpacePos.wwww;
float4 vecShadowBufferComparision = tex2D( ShadowBufferSampler, vecNormCoord);
float4 vecComparison = (vecShadowBufferComparision.rgba > vecNormCoord.zzzz);
float4 vecFrac;
vecFrac.xy = frac( vecNormCoord.xy * float2( SHADOW_BUFFER_WIDTH, SHADOW_BUFFER_HEIGHT));
vecFrac.zw = float2( 1.0f, 1.0f) - vecFrac.xy;
float4 vecBilinearWeights = vecFrac.xzxz * vecFrac.wyyw;
float shadow = dot( vecComparision, vecBilinearWeights);
The problem is that the visual result is not the same on both vendors. Even though the artefacts on Ati is not too severe, Nvidia looks much better. See the comparison pictures bellow.
As you can see the shadows is not identical and Ati hardware got black and white stripes running through the penumbra of the shadows.
I don't know the reason for this problem or if it can be fixed. I found the order in which the four samples from fetch4 operation is interpolated by trial&error. Am I doing it right? Also I tried to add a small bias to float2( SHADOW_BUFFER_WIDTH, SHADOW_BUFFER_HEIGHT) and the the artefacts became severer. Which indicate that there might be some numerical instability bug somehow? I don't know. If someone could explain what's going wrong I would be really happy.
Thanks