Colored Dithering

This shader will allow you to drag in a Bayer matrix texture (one pixel per shade in a grid), choose the amount of lightness levels, threshold for the dithering effect, amount of stops per color channel and a scale for increasing the pixelation of the screen.

Here’s a 8×8 Bayer Dithering Pattern:
https://imgur.com/a/BGXd3C8

Shader code
shader_type canvas_item;

uniform int levels : hint_range(1, 16);
uniform float threshold : hint_range(0.0, 1.0);
uniform int colors : hint_range(1, 32);
uniform int pixelate : hint_range(1, 10);
uniform sampler2D dither_texture : filter_nearest;

float dither(float raw, float dither, int depth) {
	
	float div = 1.0 / float(depth);
	float val = 0.0;
	
	for (int i = 0; i < depth; i++) {
		if (raw <= div * (float(i + 1))) {
			if ((raw * float(depth)) - float(i) <= dither * 0.999) {
				val = div * float(i);
			} else {
				val = div * float(i + 1);
			}
			break;
		}
	}
	if (raw >= 1.0) {
		val = 1.0;
	}
	return val;
}

void fragment()
{
	// Pixelate the screen
	vec2 screen_size = vec2(textureSize(TEXTURE, 0)) / float(pixelate);
	vec2 screen_sample_uv = floor(UV * screen_size) / screen_size;

	// Map the dither texture onto the screen pixels with tiling and repeating
	vec2 dither_size = vec2(textureSize(dither_texture, 0));
	vec2 dither_uv = mod(UV * screen_size, dither_size) / dither_size;
	
	// Sample the screen pixel
	vec3 screen_col = texture(TEXTURE, screen_sample_uv).rgb;

	// Sample the corresponding dither pixel luminance
	float dither_luminance = texture(dither_texture, dither_uv).r;

	// Dither each channel (r, g, and b) to the number of color quantizations via dither value
	vec3 quantized_col;
    for (int i = 0; i < 3; i++) {
        float raw_channel = screen_col[i];
        float dither_amount = threshold * dither_luminance;
        float quantized_channel = dither(raw_channel, dither_amount, levels);
        quantized_col[i] = floor(quantized_channel * float(colors)) / float(colors - 1);
    }
	
	// Apply the dithered color
	COLOR.rgb = quantized_col;
}
Tags
bayer, dither, dithered, dithering, pixel, retro
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Fake Floyd Stienberg Noise Dithering

Dithering / Screen Door Transparency

Arbitrary Color Reduction and Palette Ordered Dithering

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments