Gallery

Lava Balls

Live parameters

Geometry
0.20
0.10
Motion
1.00
Color
GLSL source
const float TAU      = 6.28318530;
const float K_SMOOTH = 0.2;       // rayon de fusion entre les blobs
const float R_BALL   = 0.1;       // rayon de chaque boule
const int   N_BALLS  = 15;
const float SPEED    = 4.0 / float(N_BALLS);

float smin(float a, float b, float k) {
    float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0);
    return mix(b, a, h) - k * h * (1.0 - h);
}

vec2 ball_pos(int i, float t) {
    float fi = float(i);
    return vec2(
        sin(t * (0.5 + fi * 0.13) + fi * 1.7) * 0.7,
        cos(t * (0.4 + fi * 0.17) + fi * 2.3) * 0.7
    );
}

vec3 ball_color(int i) {
    float fi = float(i) / float(N_BALLS);
    return 0.5 + 0.5 * cos(TAU * (fi + vec3(0.0, 0.33, 0.66)));
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 p = (2.0 * fragCoord - iResolution.xy) / iResolution.y;

    float t       = iTime * SPEED * SPEED_MULT;
    float d_final = 1e4;
    vec3  col_acc = vec3(0.0);
    float wt      = 0.0;

    for (int i = 0; i < N_BALLS; i++) {
        vec2  c  = ball_pos(i, t);
        float d  = length(p - c) - R_BALL;
        float w  = exp(-6.0 * max(d, 0.0));

        d_final  = smin(d_final, d, K_SMOOTH);
        col_acc += ball_color(i) * w;
        wt      += w;
    }

    vec3 blob_col = (col_acc / max(wt, 1e-5)) * TINT;
    vec3 col      = mix(BG_COLOR, blob_col, smoothstep(0.005, -0.005, d_final));

    fragColor = vec4(pow(col, vec3(1.0 / 2.2)), 1.0);
}