shader_type canvas_item; uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap; uniform float amount : hint_range(0.0, 1.0) = 0.5; uniform float seed = 0.0; uniform float line_density : hint_range(0.0, 1.0) = 0.4; uniform float offset_mul : hint_range(0.0, 2.0) = 1.0; uniform vec2 screen_offset = vec2(0.0); uniform vec2 screen_bend_amount = vec2(0.02, 0.02); float hash1d(float p) { return fract(sin(127.1 * p) * 43758.5453123); } void fragment() { /* =============================== Coordinate setup ================================ */ vec2 uv = SCREEN_UV; uv += screen_offset; // Screen bend (CRT-like) vec2 normal_uv = uv * 2.0 - 1.0; vec2 bend_add; bend_add.x = cos(1.5707963 * normal_uv.y) * normal_uv.x - normal_uv.x * 1.5; bend_add.y = cos(1.5707963 * normal_uv.x) * normal_uv.y - normal_uv.y * 1.5; uv += bend_add * screen_bend_amount; vec4 base_color = texture(SCREEN_TEXTURE, uv); vec2 virtual_coords = uv * 100.0; /* =============================== Row-based randomization ================================ */ float row_rand = hash1d(seed + floor(virtual_coords.y * 0.1)); float y_mul = mix(0.05, 0.8, row_rand * row_rand); float rand_strength = hash1d(floor(virtual_coords.y * y_mul) + 100.0 + row_rand); float final_amount = 0.0; float coord_add = 0.0; if (rand_strength > (1.0 - line_density)) { float distort_amount = 0.15; final_amount = amount * ( 0.5 + (hash1d(floor(virtual_coords.y * y_mul) + 1273.0 + floor(amount * 4.0)) * 2.0 - 1.0) * 0.5 ); float ra = hash1d(floor(virtual_coords.y)) * 2.0 - 1.0; coord_add = ra * distort_amount * final_amount; coord_add += (hash1d(floor(virtual_coords.x * 0.25)) * 2.0 - 1.0) * distort_amount * 0.4; coord_add *= offset_mul; } /* =============================== Intensity weighting ================================ */ float intensity = dot(base_color.rgb, vec3(0.3, 0.58, 0.12)); intensity = clamp(intensity, 0.0, 1.0); float dual_intensity = abs(intensity * 2.0 - 1.0); dual_intensity *= dual_intensity; /* =============================== Distortion sampling ================================ */ vec4 samp1 = texture(SCREEN_TEXTURE, uv + vec2(coord_add * -0.65 * dual_intensity, 0.0)); vec4 samp2 = texture(SCREEN_TEXTURE, uv + vec2(coord_add * 1.0 * dual_intensity, 0.0)); vec4 distort_color = mix(samp1, samp2, 0.5); /* =============================== Final output ================================ */ float mix_amount = dual_intensity * final_amount; COLOR = mix(base_color, distort_color, mix_amount) + vec4(vec3(intensity * final_amount * 0.05), 1.0); }