spacegame/hud/crt.gdshader
2025-05-03 18:46:56 +02:00

65 lines
No EOL
2.5 KiB
Text

/*
Shader from Godot Shaders - the free shader library.
godotshaders.com/shader/VHS-and-CRT-monitor-effect
This shader is under CC0 license. Feel free to use, improve and
change this shader according to your needs and consider sharing
the modified result to godotshaders.com.
*/
shader_type canvas_item;
uniform float scanlines_opacity : hint_range(0.0, 1.0) = 0.4;
uniform float scanlines_width : hint_range(0.0, 0.5) = 0.25;
uniform float grille_opacity : hint_range(0.0, 1.0) = 0.3;
uniform vec2 resolution = vec2(640.0, 480.0);
uniform float aberration : hint_range(-1.0, 1.0) = 0.03;
uniform float brightness = 1.4;
uniform float warp_amount :hint_range(0.0, 5.0) = 1.0;
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
vec2 warp(vec2 uv) {
vec2 delta = uv - 0.5;
float delta2 = dot(delta.xy, delta.xy);
float delta4 = delta2 * delta2;
float delta_offset = delta4 * warp_amount;
return ((uv + delta * delta_offset) - vec2(0.5, 0.5)) * 0.97 + vec2(0.5, 0.5);
}
float border (vec2 uv) {
float radius = min(warp_amount, 0.08);
radius = max(min(min(abs(radius * 2.0), abs(1.0)), abs(1.0)), 1e-5);
vec2 abs_uv = abs(uv * 2.0 - 1.0) - vec2(1.0, 1.0) + radius;
float dist = length(max(vec2(0.0), abs_uv)) / radius;
float square = smoothstep(0.96, 1.0, dist);
return clamp(1.0 - square, 0.0, 1.0);
}
void fragment() {
vec2 uv = warp(SCREEN_UV);
float time = fract(TIME / 3.0);
float x = (uv.y - time)*100.0;
uv.x += pow(100.0,-x*x) * sin(x) / 200.0;
COLOR.r = texture(SCREEN_TEXTURE, uv + vec2(aberration, 0.0) * .1).r;
COLOR.g = texture(SCREEN_TEXTURE, uv - vec2(aberration, 0.0) * .1).g;
COLOR.b = texture(SCREEN_TEXTURE, uv).b;
COLOR.a = 1.0;
vec3 grill = vec3(smoothstep(0.85, 0.95, abs(sin(uv.x * (resolution.x * 3.14159265)))), smoothstep(0.85, 0.95, abs(sin(1.05 + uv.x * (resolution.x * 3.14159265)))), smoothstep(0.85, 0.95, abs(sin(2.1 + uv.x * (resolution.x * 3.14159265)))));
COLOR.r = mix(COLOR.r, COLOR.r * grill.r, grille_opacity);
COLOR.g = mix(COLOR.g, COLOR.g * grill.g, grille_opacity);
COLOR.b = mix(COLOR.b, COLOR.b * grill.b, grille_opacity);
COLOR.r = clamp(COLOR.r * brightness, 0.0, 1.0);
COLOR.g = clamp(COLOR.g * brightness, 0.0, 1.0);
COLOR.b = clamp(COLOR.b * brightness, 0.0, 1.0);
float scanlines = 0.5;
scanlines = smoothstep(scanlines_width, scanlines_width + 0.5, abs(sin(uv.y * (resolution.y * 3.14159265))));
COLOR.rgb = mix(COLOR.rgb, COLOR.rgb * vec3(scanlines), scanlines_opacity);
COLOR *= border(uv);
}