My particular setup ( an old macbook pro with an AT x1600 and OSX 10.6.2 ) doesn’t do filtered pcf for free, like an NVIDIA supposedly would.
My understanding is that you get it “for free” on nVIDIA if you enable GL_LINEAR filtering for magnification.
So, I thought it might be fun to implement it “by hand” as it were for my GPU. I’ve done bi & trilinear filtering in C++ before, and the idea is simple enough. Take four neighboring samples and use the fractional part of the texture coordinate to blend between them.
Here’s my stab:
// ShadowMap is the shadow map
// ShadowSize is the size of the shadow map, which is square
// InvShadowSize is 1/ShadowSize
float shadow_pcf( in vec4 tc )
{
//
// simple bilinear filtering
// first bring up to whole coords, get fractionals, and then drop back to normalized coords
//
tc *= ShadowSize;
vec4 sc = floor( tc ),
fractional = tc - sc;
sc *= InvShadowSize;
fractional *= InvShadowSize;
float x1 = shadow2DProj( ShadowMap, sc ).r,
x2 = shadow2DProj( ShadowMap, sc + vec4( InvShadowSize,0,0,0 )).r,
x3 = shadow2DProj( ShadowMap, sc + vec4( 0,InvShadowSize,0,0 )).r,
x4 = shadow2DProj( ShadowMap, sc + vec4( InvShadowSize,InvShadowSize,0,0 )).r,
a = mix( x2, x1, fractional.x ),
b = mix( x4, x3, fractional.x );
return mix( b, a, fractional.y );
}
What I get is basically identical to what I got without any filtering at all. Which is to say: blocky shadows.
Any ideas?