Dithering shader not working

Hi! So I’ve been working on the following dithering shader

precision highp float;

varying vec2 vUv0;

uniform sampler2D uColorBuffer;
uniform vec2 uResolution;

const mat4x4 bayerMatrix4x4 = mat4x4(
    0.0,  0.5,  0.125, 0.625,
    0.75, 0.25,  0.875, 0.375,
    0.1875,  0.6875, 0.0625, 0.5625,
    0.9375, 0.4375,  0.8125, 0.3125
);

vec3 orderedDither(vec2 uv, float lum) {
    vec3 color = vec3(0.0);

    float threshold = 0.0;

    int x = int(uv.x * uResolution.x) % 4;
    int y = int(uv.y * uResolution.y) % 4;
    threshold = bayerMatrix4x4[y][x];

    if (lum < threshold) {
        color = vec3(0.0);
    } else {
        color = vec3(1.0); 
    }

    return color;
}

void main( ) {
    vec4 color = texture2D(uColorBuffer, vUv0);

    float lum = dot(vec3(0.2126, 0.7152, 0.0722), color.rgb);
    color.rgb = orderedDither(vUv0, lum);

    gl_FragColor = color;
}

But for some reason it renders the screen fully white. Any advice is welcome.

Looking at this, you are either rendering a black or white pixel irrespective of the original pixel color

Yes, that is the case. It seems the issue lies in sampling the threshold for pixel luminance.

vUv0 is in 0 … 1 range … you then multiply it by resolution. That should work.
but try to use gl_FragCoord.xy instead, that is in pixel space already, so no need to multiply.

1 Like

Thank you, that worked perfectly.

1 Like

see the other dithering possibilities that we used in the engine:

it also uses code from here

1 Like