shader_type canvas_item; uniform float aspect = 1.0; uniform float distortion = 1.0; uniform float radius = 1.07; uniform float alpha : hint_range(0.0, 1.0, 0.1) = 1.0; uniform float crop = 0.943; uniform vec4 crop_color : source_color = vec4(0,0,0,1); uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap; uniform float crop_feathering = 0.1; const float base_distortion = 0.99; uniform float channel_offset : hint_range(-0.1, 0.1, 0.001) = 0.005; uniform float noise_strength = 5.0; vec2 distort(vec2 p) { float d = length(p); float z = sqrt(distortion + d * d * -distortion); float r = atan(d, z) / 3.1415926535; float phi = atan(p.y, p.x); return vec2(r * cos(phi) * (1.0 / aspect) + 0.5, r * sin(phi) + 0.5); } void fragment() { vec2 xy = (SCREEN_UV * 2.0 - 1.0); xy = vec2(xy.x * aspect, xy.y); float d = length(xy); vec4 tex; if (d < radius) { vec2 distorted_uv_r = distort(xy * (base_distortion + 0.0 * channel_offset)); vec2 distorted_uv_g = distort(xy * (base_distortion + 1.0 * channel_offset)); vec2 distorted_uv_b = distort(xy * (base_distortion + 2.0 * channel_offset)); tex.r = texture(SCREEN_TEXTURE, distorted_uv_r).r; tex.g = texture(SCREEN_TEXTURE, distorted_uv_g).g; tex.b = texture(SCREEN_TEXTURE, distorted_uv_b).b; float x = (UV.x + 4.0 ) * (UV.y + 4.0 ) * (TIME * 10.0); tex = tex+vec4(mod((mod(x, 13.0) ) * (mod(x, 123.0) ), 0.01)-0.005) * noise_strength; COLOR = tex; COLOR.a = alpha; } if (d > crop) { float softness = smoothstep(crop, crop + crop_feathering, d); COLOR = mix(tex, crop_color, softness); COLOR.a = alpha; } }