Matthew Smith
Matthew Smith

Reputation: 13

Why does this algorithmic shader have bad aliasing

When I use this shader I get a really badly aliased edge

#define angle (10.0*3.1415/180.0)
void main(void)
{
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    if(((150.0)+angle*gl_FragCoord.x) > gl_FragCoord.y) {
        gl_FragColor = vec4(0,255,0,1.0);
    } else {
        gl_FragColor = vec4(0,0,0,1.0);
    }
}

You can see what I am refering to at this shadertoy: https://www.shadertoy.com/view/lsjXRR

is there a way to reduce the aliasing between the two colors (or textures if I was to use them)

Upvotes: 1

Views: 622

Answers (2)

user128511
user128511

Reputation:

I'm not sure what answer you're looking for but I'd guess it's because anti-aliasing is off on ShaderToy.

  1. Went to your link (https://www.shadertoy.com/view/lsjXRR)
  2. Opened a javascript console
  3. typed

    context.rawgl.getContextAttributes()
    

    which printed

    WebGLContextAttributes {
        failIfMajorPerformanceCaveat: false, 
        preserveDrawingBuffer: false,   
        premultipliedAlpha: false, 
        antialias: false,                      // <==--    
        stencil: true…,
    }
    

Update

So apparently MSAA anti-aliasing only happens on the edges of the primitives being drawn. Since you're drawing a single quad and your "edge" is not from the edge of a primitive but instead is computed in your fragment shader MSAA anti-aliasing has no effect.

This article explains it in more detail

If you want to anti-alias for your case either smooth out your function like @Alexander suggests, step up your canvas resolution, or apply a post processing anti-aliasing algorithm.

Upvotes: 1

Alexander Gessler
Alexander Gessler

Reputation: 46647

While turning anti-aliasing/multisampling on helps greatly (as @gman) correctly points out, you can also change your fragment function to slightly smooth out the boundary between black and green.

Edit in response to comment.

Instead of doing a hard branch, try to derive an interpolation factor around the boundary of your condition:

#define angle (10.0*3.1415/180.0)
void main(void)
{
  vec2 uv = gl_FragCoord.xy / iResolution.xy;
  float f = (((150.0)+angle*gl_FragCoord.x) - gl_FragCoord.y) * 0.003;
  float f2 = clamp(f, -0.5, 0.5) + 0.5;
  gl_FragColor = mix(vec4(0,255,0,1.0), vec4(0,0,0,1.0), f2);
}

(This moves the line, but gives an idea of how to do it). If you paste it into shadertoy, it gives you a perfectly anti-aliased (but slightly blurry) line.

Upvotes: 0

Related Questions