shader_type spatial; render_mode unshaded, cull_disabled; // Correct Godot 4.2+ screen texture uniform sampler2D screen_tex : hint_screen_texture; // Controls uniform float distortion_strength : hint_range(0.0, 6.0) = 0.75; uniform float swirl_strength : hint_range(0.0, 10.0) = 2.0; uniform float noise_amount : hint_range(0.0, 3.0) = 0.3; uniform float fog_density : hint_range(0.0, 6.0) = 1.0; uniform vec4 tint_color : source_color = vec4(1.0); // Procedural noise float hash(vec2 p) { p = fract(p * vec2(123.34, 345.45)); p += dot(p, p + 34.345); return fract(p.x * p.y); } void fragment() { vec2 uv = UV; vec2 centered = uv - vec2(0.5); float r = length(centered); // --- Fresnel (stronger distortion at edges) --- float fresnel = pow(1.0 - abs(dot(NORMAL, VIEW)), 2.0); // --- Swirl continuation --- float angle = atan(centered.y, centered.x); angle += swirl_strength * TIME; vec2 swirl_dir = vec2(cos(angle), sin(angle)); // --- Procedural noise --- float n = hash(uv * 10.0 + TIME * 0.2); // --- Final distortion vector --- vec2 distortion = centered * distortion_strength * fresnel + swirl_dir * 0.1 * distortion_strength + (n - 0.5) * noise_amount; // --- Sample the world behind the sphere --- vec3 scene_col = texture(screen_tex, SCREEN_UV + distortion).rgb; // --- Fog fade (applied LAST so it doesn't darken the distortion) --- float fog = smoothstep(0.0, fog_density, r); scene_col = mix(scene_col, tint_color.rgb, fog * 0.5); // --- Soft alpha fade --- float alpha = smoothstep(1.0, 0.3, r); ALBEDO = scene_col; ALPHA = alpha * tint_color.a; }