PCF in ATI cards

Started by
1 comment, last by Bruno 17 years, 2 months ago
Hi, I got shadowmapping working and looks great in Nvidia cards, however in ATI looks ugly, pixelated a lot. After some digging around, i found that Nvidia cards do PCF automatically from GF3 and beyond, and this is not true for ATI cards, so we must do a bilinear filtering on the shader itself. I'm tryng to do it, but i can't get this working right. This is my shader :

vec4 s1 = shadow2D(shadowMap, shadowUV);
vec4 s2 = shadow2D(shadowMap, shadowUV.xyz + vec3( mapScale,        0,0));
vec4 s3 = shadow2D(shadowMap, shadowUV.xyz + vec3(        0, mapScale,0));
vec4 s4 = shadow2D(shadowMap, shadowUV.xyz + vec3( mapScale, mapScale,0));


vec3 fractPos = fract(shadowUV * r_factor);
		
float r1 = s2.x + fractPos.x * (s1.x - s2.x);
float r2 = s4.x + fractPos.x * (s3.x - s4.x);

float shadowFactor = r2 + fractPos.y * (r1 - r2);

vec4 shadowColor = shadowColor * shadowFactor;


shadowColor += shadow2D(shadowMap, shadowUV).x;
shadowColor += shadow2D(shadowMap, shadowUV.xyz + vec3( mapScale,  mapScale, 0));
shadowColor += shadow2D(shadowMap, shadowUV.xyz + vec3( mapScale, -mapScale, 0));
shadowColor += shadow2D(shadowMap, shadowUV.xyz + vec3( mapScale,  	  0, 0));
shadowColor += shadow2D(shadowMap, shadowUV.xyz + vec3(-mapScale,  mapScale, 0));
shadowColor += shadow2D(shadowMap, shadowUV.xyz + vec3(-mapScale, -mapScale, 0));
shadowColor += shadow2D(shadowMap, shadowUV.xyz + vec3(-mapScale,  	  0, 0));
shadowColor += shadow2D(shadowMap, shadowUV.xyz + vec3(        0,  mapScale, 0));
shadowColor += shadow2D(shadowMap, shadowUV.xyz + vec3(        0, -mapScale, 0));

shadowColor = shadowColor / 10.0;
shadowColor = clamp(shadowColor, 0.0, 1.0);

This is how it looks in nvidia\ati ATI: nVidia: I'm tryng to do a filtering before doing the blur, but i'm not sure i'm doing this right., actually i'm sure i'm not doing it right, or else i wouldn't be posting :P Do you guys see anything here that is wrong ? Can someone point me to some shader code on how to make a bilinear filtering ? thanks, Bruno
Advertisement
I think your 10 value is wrong you don't seem to have 10 samples being taken.

But here is what I use.

vec3 shadowST = projCoord.xyz / projCoord.w;         float mapScale = 1.0 / shadowmapSize;         shadowColor = shadow2D(shadowmap, shadowST).r;            shadowColor += shadow2D(shadowmap, shadowST.xyz + vec3( mapScale,  mapScale, 0.0)).r;         shadowColor += shadow2D(shadowmap, shadowST.xyz + vec3( mapScale, -mapScale, 0.0)).r;         shadowColor += shadow2D(shadowmap, shadowST.xyz + vec3( mapScale,         0.0, 0.0)).r;         shadowColor += shadow2D(shadowmap, shadowST.xyz + vec3(-mapScale,  mapScale, 0.0)).r;         shadowColor += shadow2D(shadowmap, shadowST.xyz + vec3(-mapScale, -mapScale, 0.0)).r;         shadowColor += shadow2D(shadowmap, shadowST.xyz + vec3(-mapScale,         0.0, 0.0)).r;         shadowColor += shadow2D(shadowmap, shadowST.xyz + vec3(      0.0,  mapScale, 0.0)).r;         shadowColor += shadow2D(shadowmap, shadowST.xyz + vec3(      0.0, -mapScale, 0.0)).r;         shadowColor = shadowColor / 9.0; //9 samples         shadowColor += BOOST;            if(!(shadowST.x >= 0.0 && shadowST.y >= 0.0 && shadowST.x <= 1.0 && shadowST.y <= 1.0))            shadowColor = 1.0;

Thanks Mars_999
I'm divinding by 10 because i'm assuming the initial value of shadowColor to be a sample, but even if i divide by 9 the result is the same.

About your shader, i'm pretty sure if you run that on a ATI, you will have the same problem i do, you are simply bluring the shadow. If you wanna see how it will look in a ATI, before rendering to the shadow map, enable GL_NEAREST as texture filter and you will see what i mean.

This topic is closed to new replies.

Advertisement