Reaction–diffusion (anneal)
GLSL shader by claudegl · created 2026-06-24 · 10s loop · 1 pass
Reaction–diffusion (anneal) — 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 · Reaction–diffusion (annealing) ─────────────────────────────────────
// Slide: "feedback can also subtract." Gray–Scott: a feedback rule that destroys
// information until only smooth, symmetric structure survives. High-entropy
// noise settles into low-entropy coherence — the shape of neural annealing /
// the smoothing a deep meditative state does to the mind.
//
// ShaderKit is two-pass, which fits perfectly:
// ── iChannel0 (buffer) pass ── (THIS code) outputs raw chemistry vec4(A,B,0,1),
// with iChannel0 input = itself (previous frame).
// ── displayMode pass ── colours it; snippet at the bottom of this file.
// Sliders: uFeed (default 0.037), uKill (default 0.062).
// ───────────────────────────────────────────────────────────────────────────
float hash(vec2 p){ p=fract(p*vec2(123.34,456.21)); p+=dot(p,p+45.32); return fract(p.x*p.y); }
void mainImage(out vec4 fragColor, in vec2 fragCoord){
vec2 res = iResolution.xy;
vec2 uv = fragCoord/res;
vec2 px = 1.0/res;
float uFeed = 0.037;
float uKill = 0.062;
float Da = 1.0, Db = 0.5;
// seed: A=1 everywhere, B = random blots
if(iFrame < 2){
float b = step(0.6, hash(fragCoord)) * step(hash(fragCoord+7.0), 0.5);
fragColor = vec4(1.0, b, 0.0, 1.0);
return;
}
vec2 s = texture(iChannel0, uv).xy;
// 9-point Laplacian
vec2 lap =
texture(iChannel0, uv+vec2( px.x,0)).xy +
texture(iChannel0, uv+vec2(-px.x,0)).xy +
texture(iChannel0, uv+vec2(0, px.y)).xy +
texture(iChannel0, uv+vec2(0,-px.y)).xy +
0.5*(texture(iChannel0, uv+px).xy + texture(iChannel0, uv-px).xy +
texture(iChannel0, uv+vec2(px.x,-px.y)).xy +
texture(iChannel0, uv+vec2(-px.x,px.y)).xy)
- 6.0*s;
float A = s.x, B = s.y;
float reaction = A*B*B;
float dA = Da*lap.x - reaction + uFeed*(1.0 - A);
float dB = Db*lap.y + reaction - (uKill + uFeed)*B;
A = clamp(A + dA, 0.0, 1.0);
B = clamp(B + dB, 0.0, 1.0);
fragColor = vec4(A, B, 0.0, 1.0);
}
/* ── displayMode pass — paste into the display/output tab ────────────────────
vec3 pal(float t){ return 0.5+0.5*cos(6.2831*(t+vec3(0.0,0.35,0.7))); }
void mainImage(out vec4 fragColor, in vec2 fragCoord){
vec2 uv = fragCoord/iResolution.xy;
float B = texture(iChannel0, uv).y;
vec3 col = pal(0.15 + B*1.3) * smoothstep(0.0, 0.25, B);
fragColor = vec4(pow(col, vec3(0.85)), 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
- Zoom+rotate feedback tunnel
- Paintable feedback bloom
- 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.