1bit ordered bayer matrix

Hi guys

I’m having a problem trying to fix my 1bit ordered dithering shader

// Ordered dithering aka Bayer matrix dithering
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform vec2 resolution;
uniform float pixelSize;
uniform float gamma;
uniform float contrast;
uniform int invert;
uniform sampler2D textureImage;

void main()
{
	vec2 uv = gl_FragCoord.xy / resolution.xy; 
	
	vec2 pseudoPixel = floor( gl_FragCoord.xy / pixelSize );
	vec2 pseudoResolution = floor( resolution.xy / pixelSize );
	vec2 pseudoUv = pseudoPixel / pseudoResolution;
	
	vec4 color = v_vColour * texture2D( gm_BaseTexture, pseudoUv );
	float alpha = 1.0;
	
	vec2 tuv = gl_FragCoord.xy / 8.0;
	tuv *= 17.0;
	tuv = fract(tuv);
	
	vec4 tdither = texture2D( textureImage, tuv );
	
	vec4 lum = vec4(0.299, 0.587, 0.114, 0);
	
	float dither = dot(tdither, lum);
	float grayscale = dot(color, lum) * gamma;
	grayscale = (grayscale - 0.5) * contrast + 0.5;
	
	vec3 col = vec3(step(dither,grayscale));
	
	if(invert == 0) {
		gl_FragColor = vec4(col, alpha);
	} else {
		gl_FragColor = vec4(1.0 - col, alpha);
	}
}

I’m trying to make it for a videogame so I decided to put some uniform to handle some things like gamma, contrast, invert colors, pixel size

I studied a lot of bayer matrix shaders to understand this that I wrote
the point is that I’m using it inside game maker studio 2 which has some differences writing it

I was not able to write double arrays like this

//1Bit ordered dithering patterns
vec3 dither_8(vec2 pos, float val) {

	const int mat[] = int[](
	0, 48, 12, 60, 3, 51, 15, 63,
	32, 16, 44, 28, 35, 19, 47, 31,
	8, 56, 4, 52, 11, 59, 7, 55,
	40, 24, 36, 20, 43, 27, 39, 23,
	2, 50, 14, 62, 1, 49, 13, 61,
	34, 18, 46, 30, 33, 17, 45, 29,
	10, 58, 6, 54, 9, 57, 5, 53,
	42, 26, 38, 22, 41, 25, 37, 21
	);

or like this

int dither[8][8] = {
		{ 0, 32, 8, 40, 2, 34, 10, 42	},
		{48, 16, 56, 24, 50, 18, 58, 26	},
		{12, 44, 4, 36, 14, 46, 6, 38	},
		{60, 28, 52, 20, 62, 30, 54, 22	},
		{ 3, 35, 11, 43, 1, 33, 9, 41	},
		{51, 19, 59, 27, 49, 17, 57, 25	},
		{15, 47, 7, 39, 13, 45, 5, 37	},
		{63, 31, 55, 23, 61, 29, 53, 21	} 
	};

so I decided to try sample a texture of a bayer matrix 8x8 px
try to put on top of my source image (game canvas)
multiply the texture to cover the whole canvas
and render a step function to have only black or white

in this moment I have a problem with the size of the dithering, because is static and change the quality of my final result in base of the canvas size

for example if I have a little canvas but I make it fullscreen it changes the detail of the textures, because the dither remain of a certain size

I really would like to be able to handle the dither size with a uniform, to do some debug tests and understand what is the size that I should use
also to be able to change the value in game to give some transition effect

I guess the dither size could be
or linked to the pixel size
or unlinked, maybe better so I can achieve more effects having two different values and in case link it to the pixel size outside the shader

I tried a lot of ways, I’m a little bit stuck

hope you guys can help me with this, because I’m doing very good stuff for it and I would like to fix it very soon to keep going with my project

thank you so much

I got a better shader now, adding a vignette effect with lots of uniforms to change all parameters dynamically

// Ordered dithering aka Bayer matrix dithering
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform vec2 resolution;

uniform float pixelSize;

uniform float gamma;
uniform float contrast;

uniform int invert;

uniform int vignette;

uniform float vsize;
uniform float vouter;
uniform float vfalloff;
uniform float valpha;

uniform sampler2D textureImage;

void main()
{
    vec2 uv = gl_FragCoord.xy / resolution.xy; 
    float center = vsize - distance(vec2(0.5),uv);
    
    vec2 pseudoPixel = floor( gl_FragCoord.xy / pixelSize );
    vec2 pseudoResolution = floor( resolution.xy / pixelSize );
    vec2 pseudoUv = pseudoPixel / pseudoResolution;
    
    vec4 color = v_vColour * texture2D( gm_BaseTexture, pseudoUv );
    float alpha = 1.0;
    
    vec2 tuv = gl_FragCoord.xy / 8.0;
    tuv *= 17.0;
    tuv = fract(tuv);
    
    vec4 tdither = texture2D( textureImage, tuv );
    
    vec4 lum = vec4(0.299, 0.587, 0.114, 0);
    
    if(vignette == 1) {
        vec3 vcol = vec3(smoothstep(vouter, vouter + vfalloff, center));
        color.rgb = mix(color.rgb, color.rgb * vcol, valpha);
    }
    
    float dither = dot(tdither, lum);
    float grayscale = dot(color, lum) * gamma;
    grayscale = (grayscale - 0.5) * contrast + 0.5;
    
    vec3 col = vec3(step(dither,grayscale));
    
    if(invert == 0) {
        gl_FragColor = vec4(col, alpha);
    } else {
        gl_FragColor = vec4(1.0 - col, alpha);
    }
}

I still have the problem on the dithering size

I guess I got something wrong here

vec2 tuv = gl_FragCoord.xy / 8.0;
tuv *= 17.0;
tuv = fract(tuv);

dithering size should be linked to the game window size
(currently if I switch to fullscreen it changes the detail of the picture)

and should be able to change the parameter with a uniform to have more control