#version 100 precision mediump float; uniform float u_time; uniform vec2 u_resolution; uniform vec2 u_mouse; uniform sampler2D u_backbuffer; // Gray-Scott parameters // standard "spots" / coral #define DA 1.0 #define DB 0.5 #define FEED 0.055 #define KILL 0.062 #define DT 1.0 void main() { vec2 pixel = 1.0 / u_resolution; vec2 uv = gl_FragCoord.xy / u_resolution; // Read current state vec4 state = texture2D(u_backbuffer, uv); float a = state.r; float b = state.g; // Laplaclan (convolution) // 0.05 0.2 0.05 // 0.2 -1 0.2 // 0.05 0.2 0.05 vec4 sum = vec4(0.0); sum += texture2D(u_backbuffer, uv + vec2(-1.0, -1.0) * pixel) * 0.05; sum += texture2D(u_backbuffer, uv + vec2( 0.0, -1.0) * pixel) * 0.2; sum += texture2D(u_backbuffer, uv + vec2( 1.0, -1.0) * pixel) * 0.05; sum += texture2D(u_backbuffer, uv + vec2(-1.0, 0.0) * pixel) * 0.2; sum -= state * 1.0; sum += texture2D(u_backbuffer, uv + vec2( 1.0, 0.0) * pixel) * 0.2; sum += texture2D(u_backbuffer, uv + vec2(-1.0, 1.0) * pixel) * 0.05; sum += texture2D(u_backbuffer, uv + vec2( 0.0, 1.0) * pixel) * 0.2; sum += texture2D(u_backbuffer, uv + vec2( 1.0, 1.0) * pixel) * 0.05; // Reaction-Diffusion logic // A' = A + (Da * lapA - A*B*B + f*(1-A)) * dt // B' = B + (Db * lapB + A*B*B - (k+f)*B) * dt float lapA = sum.r; float lapB = sum.g; float abb = a * b * b; float nA = a + (DA * lapA - abb + FEED * (1.0 - a)) * DT; float nB = b + (DB * lapB + abb - (KILL + FEED) * b) * DT; // Clamp nA = clamp(nA, 0.0, 1.0); nB = clamp(nB, 0.0, 1.0); // Mouse Interaction (Add B) float dist = distance(gl_FragCoord.xy, u_mouse); if (dist < 20.0 && u_mouse.x > 0.0) { nB = 0.9; } // Initialization (random noise at start) if (u_time < 0.5) { if (fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453) > 0.99) { nB = 1.0; } else { nB = 0.0; nA = 1.0; } } gl_FragColor = vec4(nA, nB, 0.0, 1.0); }