#version 140 in vec2 coords; out vec4 color; // use this fragment shader as a starting point for new ones uniform sampler2D u_previous; uniform sampler2D u_texture_0; uniform vec2 u_resolution; uniform float u_time; #define PIXEL (1.0 / u_resolution) vec4 lookup(vec2 p, float dx, float dy) { vec2 uv = p + vec2(dx, dy) * PIXEL; vec4 c = texture(u_previous, uv, 0.).rgba; c = c*2.-1.; float mass = texture(u_texture_0, uv, 0.).r * 0.99; // if (texture(u_texture_0, uv, 0.).r > 0.5) { return (1.0 - mass) * c + (mass * vec4( vec2(dx, dy), -vec2(dx, dy) )); // } // return c; } float sim(vec2 a, vec2 b) { return dot(normalize(a), normalize(b)); } vec4 update(vec2 p) { vec2 force = vec2(0.0); vec2 force_back = vec2(0.0); float tot_s = 0.0; float tot_sb = 0.0; vec4 c = lookup(p, 0, 0); vec2 baseline = vec2(c.r, c.g); // + vec2(c.b, c.a); for (float i = -1; i <= 1; i++) { for (float j = -1; j <= 1; j++) { vec4 n = lookup(p, i, j); { float s = sim(n.xy, baseline); vec2 new = vec2(i, j) + n.xy; float strength = sqrt(length(new)); if (s >= 0.0) { force += n.xy * strength * s; tot_s += strength * s; } else { force_back += n.xy * strength * -s; tot_sb += strength * -s; } } { float s = sim(n.ba, baseline); vec2 new = vec2(i, j) + n.ba; float strength = sqrt(length(new)); if (s >= 0.0) { force += n.ba * strength * s; tot_s += strength * s; } else { force_back += n.ba * strength * -s; tot_sb += strength * -s; } } } } return vec4( force / (tot_s + 0.008), force_back / (tot_sb + 0.008)); } float rand(vec2 co){ return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); } void main() { if (u_time < 1.0) { color = vec4( rand(coords), rand(coords + 1.0), rand(coords + 2.0), rand(coords + 3.0) ); // color = vec4(0.5); return; } vec4 new = update(coords); color = new*.5+.5; }