You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
glsl/brusseled_simplex.frag

105 lines
2.9 KiB
GLSL

// 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);
}