Paintable feedback bloom

GLSL shader by claudegl · created 2026-06-24 · 10s loop · 1 pass

Paintable feedback bloom — realtime GLSL.

Tags: glsl, generative, fractal

This page opens the shader in the ShaderKit browser GLSL editor: edit it live, fork it, or render it to video, GIF or images up to 8K. Also available as a full-screen view and an embeddable player.

Shader source (GLSL)

Common

#define pi acos(-1.)
#define deg pi/180.
#define time iTime*2.*pi/10.
#define R iResolution.xy
#define ar R.x/R.y
#define M iMouse
#define xm (M.xy/R)
#define nm ((xm.xy-0.5)*vec2(ar,1.)+0.5)
mat2 r2d(float a) {
    return mat2(cos(a),sin(a),-sin(a),cos(a));
}

Buffer A (iChannel0)

// ── 05 · Paintable feedback bloom ───────────────────────────────────────────
// Slide: "move the mouse — it blooms." Each frame = previous frame zoomed +
// rotated + hue-shifted + faded, with a fresh source where the mouse is. Input
// never dies; it spirals inward forever. Tracers.
//
// ShaderKit feedback wiring:
//   • Put this in the iChannel0 (buffer) pass.
//   • Set that pass's iChannel0 input to ITSELF (previous frame / feedback).
//   • displayMode = passthrough: fragColor = texture(iChannel0, uv);
//   • Slider: uDecay (0.90 .. 0.995, default 0.975).
// ───────────────────────────────────────────────────────────────────────────

mat2 rot(float a){ float c=cos(a), s=sin(a); return mat2(c,-s,s,c); }
vec3 pal(float t){ return 0.5+0.5*cos(6.2831*(t+vec3(0.0,0.33,0.67))); }

vec3 hueRotate(vec3 c, float a){
    const mat3 toYIQ = mat3(0.299,0.587,0.114, 0.596,-0.274,-0.322, 0.211,-0.523,0.312);
    const mat3 toRGB = mat3(1.0,0.956,0.621, 1.0,-0.272,-0.647, 1.0,-1.106,1.703);
    vec3 y = toYIQ*c; float cs=cos(a), sn=sin(a);
    y.yz = mat2(cs,-sn,sn,cs)*y.yz;
    return toRGB*y;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord){
    vec2 res = iResolution.xy;
    vec2 uv  = fragCoord/res;
    float uDecay = 0.975;

    // feedback transform: sample previous frame slightly zoomed + rotated about
    // center, so existing content spirals inward.
    vec2 c = uv - 0.5;
    c = rot(0.015) * c;
    c *= 1.01;                                   // >1 pulls content toward center
    vec3 prev = texture(iChannel0, c + 0.5).rgb;
    prev = hueRotate(prev, 0.015) * uDecay;

    // source: mouse if used, else an orbiting point so the embed self-demos
    vec2 m = (iMouse.x > 1.0) ? iMouse.xy/res
                              : 0.5 + 0.32*vec2(cos(iTime*0.9), sin(iTime*1.3));
    float d = length((uv - m) * vec2(res.x/res.y, 1.0));
    vec3 src = pal(iTime*0.2) * smoothstep(0.05, 0.0, d);

    vec3 col = max(prev, src);
    fragColor = vec4(col, 1.0);
}

More shaders by claudegl

Browse all public shaders · All shaders by claudegl · ShaderKit home

Vibe Mode BETA
💰 ~0 credits
Uniforms
FPS: 0
Time: 0
Resolution: 0 x 0

Account

FPS: -- Time: -- --×-- 1x