#include // The engine supplies the backing texture and its physical size. uniform vec2 u_texture_size; uniform vec2 u_origin; uniform vec2 u_extent; uniform float u_strength; uniform sampler2D u_background; out vec4 frag_color; vec2 sampleUV(vec2 point) { vec2 uv = point / u_texture_size; #ifdef IMPELLER_TARGET_OPENGLES uv.y = 1.0 - uv.y; #endif return clamp(uv, vec2(0.001), vec2(0.999)); } void main() { vec2 point = FlutterFragCoord().xy; vec2 centre = u_origin + u_extent * 0.5; vec2 local = point - centre; float radius = max(u_extent.y * 0.5, 1.0); float spine = max(u_extent.x * 0.5 - radius, 0.0); vec2 outward = local - vec2(clamp(local.x, -spine, spine), 0.0); float distance = length(outward); vec2 normal = outward / max(distance, 0.001); float depth = radius - distance; float rim = 1.0 - smoothstep(0.0, radius * 0.46, depth); // Curved glass bends rays most at its edge, with subtle centre magnification. vec2 ray = centre + local / (1.0 + u_strength * 0.075) - normal * rim * rim * radius * u_strength * 0.23; vec4 colour = texture(u_background, sampleUV(ray)); float dispersion = u_strength * rim * 0.65; colour.r = texture(u_background, sampleUV(ray + normal * dispersion)).r; colour.b = texture(u_background, sampleUV(ray - normal * dispersion)).b; // The curved rim catches nearby background light as well as transmitting it. // Reflection follows live pixels instead of being a painted white outline. float facing = max(0.0, dot(normal, normalize(vec2(-0.5, -0.8)))); float edge_light = pow(rim, 4.0) * u_strength * facing; vec4 reflected = texture(u_background, sampleUV(point + normal * radius * 0.40)); colour = mix(colour, reflected, min(edge_light * 0.18, 0.22)); // A grazing-angle white reflection gives the curved rim visible thickness; // the broad centre continues to transmit the live, lightly softened scene. colour.rgb = mix(colour.rgb, vec3(colour.a), min(edge_light * 0.12, 0.16)); float reflection = edge_light * 0.07; colour.rgb = min(colour.rgb + reflection * colour.a, vec3(colour.a)); frag_color = colour; }