From the web

Metaballs

Liquid blobs that merge and split as they drift.

OGL · GLSL · Signed distance fields

Each blob contributes a smooth field; wherever the summed field crosses a threshold, the surface appears. Merging comes for free.

Every blob is a circle signed distance function, and the circles are merged with a polynomial smooth minimum, so nearby blobs bulge into each other and separate again without any extra logic. The surface is where the combined distance crosses zero. Fill, accent rim and glow are all derived from that single distance value. Blob positions are Lissajous paths computed on the CPU and passed as a vec3 uniform array; the pointer is one more circle.

float sdCircle(vec2 p, vec3 blob) {
  return length(p - blob.xy) - blob.z;
}

// polynomial smooth minimum
float smin(float a, float b, float k) {
  float h = max(k - abs(a - b), 0.0) / k;
  return min(a, b) - h * h * k * 0.25;
}

// aspect-correct space: 1.0 = min(width, height)
vec2 p = (gl_FragCoord.xy - 0.5 * uRes) / minRes;

float d = 1e3;
for (int i = 0; i < 16; i++) {
  if (i >= uCount) break;
  d = smin(d, sdCircle(p, uBlobs[i]), uK);
}
if (uPointer.z > 0.001) d = smin(d, sdCircle(p, uPointer), uK);

float inside = 1.0 - smoothstep(-aa, aa, d);
float rim = smoothstep(-0.002, 0.001, d) * (1.0 - smoothstep(0.004, 0.011, d));
vec3 col = BG + ACCENT * exp(-max(d, 0.0) * 22.0) * 0.10;
col = mix(col, ACCENT, rim);
col = mix(col, fill, inside);