Retro Postprocessor

Features:

– Simple dithering effect

– Configurable color quantization

– Configurable pixel-iness

– Configurable lens distortion

Apply this to a SubViewportContainer. Don’t know how to use those? Here’s a tutorial.

Tested with Godot version 4.7.1 (but that’s not available from the dropdown for some reason).

Shader code
shader_type canvas_item;

uniform int y_res = 240;
uniform float fisheye = 0.1;
uniform float color_depth = 8.0;

vec2 curve(vec2 uv) {

	uv = (uv - 0.5) * 2.0;
	uv *= 1.1;
	uv *= 1.0 + uv.x * uv.x * uv.x * uv.x * uv.y * uv.y * uv.y * uv.y * fisheye;
	uv  = (uv / 2.0) + 0.5;
	uv =  uv * 0.92 + 0.04;

	return uv;
}
void fragment() {
	
	vec2 resolution = vec2(float(y_res) * TEXTURE_PIXEL_SIZE.y / TEXTURE_PIXEL_SIZE.x, float(y_res));
	vec2 uv = curve(UV);
	vec2 pixel = floor(uv * resolution);
	uv = pixel / resolution;
    
	vec3 col;
	
	if (uv.x < 0.0 || uv.y < 0.0 || uv.x > 1.0 || uv.y > 1.0) {
		col = vec3(0.0);
	} else {
		col = texture(TEXTURE, uv).xyz;
	}

	// quantize channels with dithering (only half of all pixels round to nearest, other half round down)
	col *= color_depth;
	if (floor(mod(pixel.x, 2.0)) == floor(mod(pixel.y, 2.0))) {

		if (mod(col.r, 1.0) > 0.5) {
			col.r = ceil(col.r);
		} else {
			col.r = floor(col.r);
		}

		if (mod(col.g, 1.0) > 0.5) {
			col.g = ceil(col.g);
		} else {
			col.g = floor(col.g);
		}

		if (mod(col.b, 1.0) > 0.5) {
			col.b = ceil(col.b);
		} else {
			col.b = floor(col.b);
		}
	} else {
		col = floor(col);
	}
	col /= color_depth;

    COLOR = vec4(col, 1.0);
}
Live Preview
Tags
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.

More from dairycultist

Related shaders

guest

0 Comments
Oldest
Newest Most Voted