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);
}