// Author @patriciogv - 2015 - patriciogonzalezvivo.com // Modified to use Brusselator reaction-diffusion system #ifdef GL_ES precision mediump float; #endif uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // Brusselator parameters const float A = 1.0; const float B = 2.5; const float Du = 0.1; // Diffusion rate for u const float Dv = 0.05; // Diffusion rate for v vec2 skew (vec2 st) { vec2 r = vec2(0.0); r.x = 1.1547*st.x; r.y = st.y+0.5*r.x; return r; } vec3 simplexGrid (vec2 st) { vec3 xyz = vec3(0.0); vec2 p = fract(skew(st)); if (p.x > p.y) { xyz.xy = 1.0-vec2(p.x,p.y-p.x); xyz.z = p.y; } else { xyz.yz = 1.0-vec2(p.x-p.y,p.y); xyz.x = p.x; } return fract(xyz); } // Brusselator reaction function vec2 brusselator(vec2 uv, float time) { float scale = 10.0; vec2 st = uv * scale; // Initialize concentrations float u = 0.5 + 0.3 * sin(st.x * 3.14159) * cos(st.y * 3.14159); float v = 0.25 + 0.2 * cos(st.x * 2.0 * 3.14159) * sin(st.y * 2.0 * 3.14159); // Multiple iterations for the reaction-diffusion for(int i = 0; i < 5; i++) { // Brusselator reaction terms float reaction_u = A - (B + 1.0) * u + u * u * v; float reaction_v = B * u - u * u * v; // Simple Laplacian (diffusion) float laplacian_u = sin(st.x * 6.28318 + time) * 0.1 + sin(st.y * 6.28318 + time * 0.7) * 0.1; float laplacian_v = cos(st.x * 6.28318 + time * 0.5) * 0.1 + cos(st.y * 6.28318 + time * 1.2) * 0.1; // Update concentrations (Euler integration) u += 0.1 * (reaction_u + Du * laplacian_u); v += 0.1 * (reaction_v + Dv * laplacian_v); // Clamp to reasonable values u = clamp(u, 0.0, 2.0); v = clamp(v, 0.0, 2.0); // Advance time slightly for each iteration time += 0.05; } return vec2(u, v); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec3 color = vec3(0.0); // Get Brusselator concentrations vec2 bruss = brusselator(st, u_time * 0.5); // Scale the space to see the grid st *= 10.; // Use Brusselator concentrations to modulate the grid // u concentration affects red channel, v affects green float u_mod = bruss.x * 2.0; float v_mod = bruss.y * 2.0; // Create dynamic grid using Brusselator patterns vec2 modulated_st = st + vec2(u_mod * 0.5, v_mod * 0.3); // Subdivide the grid into equilateral triangles // using Brusselator values to animate the grid color = simplexGrid(modulated_st * (1.0 + bruss.x * 0.5)); // Add some color from the Brusselator concentrations color.r += bruss.x * 0.3; color.g += bruss.y * 0.2; color.b += (1.0 - bruss.x) * 0.2; gl_FragColor = vec4(color, 1.0); }