From the web

Liquid Glass

A lens of glass that bends and splits what's behind it.

OGL · GLSL

A shader models a rounded glass slab: the surface normal bends the background, edges refract hardest, and each color channel bends a little differently.

A fragment shader evaluates the signed distance to a rounded rectangle for every pixel. Inside the lens, a smoothstep over the outer 30% gives a height profile, and its slope along the SDF gradient bends the texture lookup, strongest at the rim. Red, green and blue are sampled with slightly different offsets for the chromatic split, and a thin rim highlight lit from the top left finishes the glass. The background is a 2D canvas uploaded once per resize as a texture.

float d = sdRoundBox(p, uHalf, uRadius);   // < 0 inside the lens
float depth = -d;
float edge = min(uHalf.x, uHalf.y) * 0.30;
float h = smoothstep(0.0, edge, depth);

// outward direction = gradient of the signed distance
vec2 e = vec2(1.0, 0.0);
vec2 outward = normalize(vec2(sdf(p + e.xy) - sdf(p - e.xy),
                              sdf(p + e.yx) - sdf(p - e.yx)) + 1e-5);

// slope of the height profile, strongest at the rim
float slope = pow(1.0 - h, 1.6);
vec2 offset = outward * slope * uRefraction * 0.08 * minRes / uRes;

// chromatic split: each channel bends a different amount
float ca = uChromatic * 0.35;
vec3 col;
col.r = blur(uv + offset * (1.0 - ca), blurPx).r;
col.g = blur(uv + offset,              blurPx).g;
col.b = blur(uv + offset * (1.0 + ca), blurPx).b;

// thin specular rim, lit from the top left
float facing = dot(outward, normalize(vec2(-1.0, 1.0)));
float band = 1.0 - smoothstep(0.0, 2.6 * uDpr, depth);
col += vec3(1.0) * band * (pow(max(facing, 0.0), 2.2) * 0.85 + 0.10);