Soft Retro with Blur

A gentle PS2 type shader with blur and noise. Made with ChatGPT

 

Instructions

Add a ColorRect to your scene, go to materials, make a shader, and paste this code in. Make sure to set the mouse Filter to Pass. 

Add this script to your ColorRect:

extends ColorRect

 

func _process(_delta):

if material and material is ShaderMaterial:

material.set_shader_parameter(“screen_size”, get_viewport().get_visible_rect().size)

Shader code
shader_type canvas_item;

uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
uniform vec2 screen_size = vec2(1280.0, 720.0);

// Final soft PS2-style settings
uniform float pixel_size : hint_range(0.5, 8.0) = 0.8;
uniform float color_levels : hint_range(4.0, 64.0) = 48.0;
uniform float dither_strength : hint_range(0.0, 1.0) = 0.03;
uniform float scanline_strength : hint_range(0.0, 1.0) = 0.015;
uniform float chroma_amount : hint_range(0.0, 2.0) = 0.2;
uniform float noise_amount : hint_range(0.0, 0.2) = 0.008;
uniform float warp_strength : hint_range(0.0, 1.0) = 0.04;
uniform float vignette : hint_range(0.0, 1.0) = 0.06;
uniform float blur_strength : hint_range(0.0, 2.0) = 0.5;

float rand(vec2 co) {
	return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);
}

vec3 blur_texture(sampler2D tex, vec2 uv, vec2 size, float radius) {
	vec2 pixel = vec2(1.0) / size;
	vec3 col = texture(tex, uv).rgb * 0.36;
	col += texture(tex, uv + pixel * vec2(radius, 0.0)).rgb * 0.16;
	col += texture(tex, uv - pixel * vec2(radius, 0.0)).rgb * 0.16;
	col += texture(tex, uv + pixel * vec2(0.0, radius)).rgb * 0.16;
	col += texture(tex, uv - pixel * vec2(0.0, radius)).rgb * 0.16;
	return col;
}

void fragment() {
	vec2 uv = FRAGCOORD.xy / screen_size;

	// Light CRT-style warp
	vec2 center = vec2(0.5);
	vec2 warp = uv - center;
	uv -= warp * warp_strength * dot(warp, warp);

	// Slight chromatic aberration
	vec2 chroma_offset = warp * chroma_amount * 0.001;
	vec4 col;
	col.r = texture(SCREEN_TEXTURE, uv + chroma_offset).r;
	col.g = texture(SCREEN_TEXTURE, uv).g;
	col.b = texture(SCREEN_TEXTURE, uv - chroma_offset).b;
	col.a = 1.0;

	// Gentle soft blur (like PS2’s bilinear texture filtering)
	col.rgb = mix(col.rgb, blur_texture(SCREEN_TEXTURE, uv, screen_size, 1.0), blur_strength * 0.4);

	// Slightly reduce color precision
	col.rgb = floor(col.rgb * color_levels) / color_levels;

	// Minimal dithering
	col.rgb += (rand(uv * screen_size) - 0.5) * (1.0 / color_levels) * dither_strength;

	// Barely-visible scanlines
	col.rgb *= 1.0 - scanline_strength * (sin(uv.y * screen_size.y * 3.1415) * 0.5 + 0.5);

	// Tiny film noise
	col.rgb += (rand(uv * screen_size * 0.5) - 0.5) * noise_amount;

	// Very soft vignette
	float vign = smoothstep(1.0, 0.5, length(uv - 0.5) * vignette * 3.0);
	col.rgb *= vign;

	COLOR = col;
}
Tags
blur, Goated, Post processing, PS2, 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

Drop-in PBR 2d lighting system with soft shadows and ambient occlusion

Dynamic 2D Lights and Soft Shadows

Canvas Item Soft Drop Shadow

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments