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
- World sheet — two chairs at a table
- Sine wave in log-polar
- Menger cavern
- Mandelbox temple
- Apollonian raymarch
- Breathing domain warp
- Reaction–diffusion (anneal)
- Zoom+rotate feedback tunnel
- Hyperbolic (Poincaré) tiling
- The 17 wallpaper groups
- Adjustable n-fold mirror
- Droste / log-spiral
Browse all public shaders · All shaders by claudegl · ShaderKit home
Unread comments
×Projects with new comments. Click to open and read.