PDA

View Full Version : Coverage Sampling Anti-aliasing artefacts



Don't Disturb
07-18-2008, 08:46 AM
Hi all,
I'm getting some weird artefacts at the edges of some objects when I use CSAA with 16 coverage samples and 4 colour samples:
http://www.aliparr.net/4mike/csaa.png
This occurs on a GeForce 8800 GTS and 9800 GTX, both with 175.16 drivers.
Does anyone have any idea what I'm doing wrong that could cause this?

Don't Disturb
07-18-2008, 11:29 AM
After further investigation, I've discovered that using a custom varying in a GLSL shader instead of gl_Color causes this.

e.g. using the following vertex shader:

varying vec4 col;
void main(){
gl_Position = ftransform();
vec3 normal = gl_NormalMatrix * gl_Normal;
gl_FrontColor = col = vec4(normal.zzz, 1.0);
}

this fragment shader works fine:

varying vec4 col;
void main(){
gl_FragColor = gl_Color;
}

but this fragment shader results in artefacts:

varying vec4 col;
void main(){
gl_FragColor = col;
}

Full code available here if you want to see for yourself (requires glew): http://paste.cbwhiz.com/282

Seth Hoffert
07-18-2008, 02:02 PM
This is because gl_FrontColor gets clamped to [0.0, 1.0], and a custom varying does not. :)

Don't Disturb
07-18-2008, 05:29 PM
How does that explain the artefacts? The values stored in col by the vertex shader are already between 0 and 1. Floating point errors may cause the values to fall outside that range slightly, but that shouldn't result in outputting completely the wrong value.

Xmas
07-18-2008, 05:47 PM
That looks odd. Have you tried using centroid interpolation? E.g. (in both shaders):

#extension GL_EXT_gpu_shader4 : require
centroid varying vec4 col;

Seth Hoffert
07-18-2008, 06:21 PM
I'd be interested in knowing whether a clamp() helps or not with the user-defined varying... perhaps it's a derivative issue (in which case centroid may help as Xmas pointed out).

Don't Disturb
07-21-2008, 03:09 AM
Thanks Xmas - centroid fixed it! So it seems nvidia's extrapolation method is broken. I've submitted a bug report to them so hopefully they'll get it fixed soon and it won't be necessary to declare every single varying as centroid!

HexCat - clamping in both the vertex shader and fragment shader didn't make a difference.

Dark Photon
07-21-2008, 07:01 AM
Thanks Xmas - centroid fixed it! So it seems nvidia's extrapolation method is broken.
Are you sure? Read this first: GLSL: Center or Centroid? (Or When Shaders Attack!) (http://www.opengl.org/pipeline/article/vol003_6/)

Don't Disturb
07-21-2008, 07:29 AM
Yes I'm sure, that's the first article I read. Centroid definitely shouldn't be necessary when a fragment shader is as simple as the one I posted above.

gybe
07-21-2008, 10:18 AM
I look at your code and me too I just think it's a centroid problem. If you want to prove it's a NVIDIA problem, I think you should improve your test.

Don't Disturb
07-22-2008, 04:02 AM
gybe - please elaborate. And if you can tell me how to rewrite the shaders so that centroid isn't necessary then please do!

Don't Disturb
07-22-2008, 04:34 AM
I think I've figured it out now - for triangles at a near-perpendicular angle to the viewport, the w-coordinate may be extrapolated to a negative number, which combined with a negative extrapolated varying result will giving large values.
If this is correct, if you're using multisampling and your geometry may be viewed from any angle then always declare your varyings as centroid (with the exception of using dFdx and dFdy) or you may get artefacts.
This (http://www.opengl.org/pipeline/article/vol003_6/) needs to change its recommendations accordingly.