cool stuff
This commit is contained in:
66
shaders/fluid.frag
Normal file
66
shaders/fluid.frag
Normal file
@@ -0,0 +1,66 @@
|
||||
#version 100
|
||||
precision mediump float;
|
||||
|
||||
uniform float u_time;
|
||||
uniform vec2 u_resolution;
|
||||
uniform vec2 u_mouse;
|
||||
uniform sampler2D u_backbuffer;
|
||||
|
||||
// Fluid Parameters
|
||||
#define DT 0.15
|
||||
#define VISCOSITY 0.99
|
||||
#define FADE 0.995
|
||||
|
||||
// Pseudo-random
|
||||
float rand(vec2 co){
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 pixel = 1.0 / u_resolution;
|
||||
vec2 uv = gl_FragCoord.xy / u_resolution;
|
||||
|
||||
// 1. Read current state (Vel, Density)
|
||||
if (u_time < 0.5 || u_resolution.x < 1.0) {
|
||||
gl_FragColor = vec4(0.5, 0.5, 0.0, 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 state = texture2D(u_backbuffer, uv);
|
||||
vec2 vel = state.xy; // velocity range [-1, 1]? we store as [0,1]. Need remap.
|
||||
// Actually simpler to store raw flow in 0..1 range whre 0.5 is 0 velocity.
|
||||
// Let's assume 0.5 is 0.
|
||||
vec2 v = (vel - 0.5) * 2.0;
|
||||
|
||||
float density = state.z;
|
||||
|
||||
// 2. Advection (move state by velocity)
|
||||
// We look *back* along velocity to find where the current content came from.
|
||||
vec2 coord = uv - v * pixel * 5.0; // Scale velocity effect
|
||||
vec4 advected = texture2D(u_backbuffer, coord);
|
||||
|
||||
vec2 new_v = (advected.xy - 0.5) * 2.0;
|
||||
float new_d = advected.z;
|
||||
|
||||
// 3. Mouse Interaction (Splat)
|
||||
float d = distance(gl_FragCoord.xy, u_mouse);
|
||||
if (d < 30.0 && u_mouse.x > 0.0) {
|
||||
// Add density
|
||||
new_d += 0.5;
|
||||
|
||||
// Add velocity (push away from mouse or just random?)
|
||||
// Ideally we need mouse delta (velocity). u_mouse is just pos.
|
||||
// We can just add a radial force or flow?
|
||||
// Let's just add some noise/movement
|
||||
new_v += vec2(rand(uv + u_time) - 0.5, rand(uv + u_time + 1.0) - 0.5) * 1.0;
|
||||
}
|
||||
|
||||
// 4. Decay (Viscosity/Dissipation)
|
||||
new_v *= VISCOSITY;
|
||||
new_d *= FADE;
|
||||
|
||||
// Remap velocity back to 0..1
|
||||
vel = new_v * 0.5 + 0.5;
|
||||
|
||||
gl_FragColor = vec4(vel, new_d, 1.0);
|
||||
}
|
||||
@@ -1,31 +1,56 @@
|
||||
#version 100
|
||||
precision mediump float;
|
||||
precision highp float;
|
||||
|
||||
uniform float u_time;
|
||||
uniform vec2 u_resolution;
|
||||
uniform float u_zoom;
|
||||
uniform vec2 u_center;
|
||||
|
||||
void main() {
|
||||
vec2 uv = (gl_FragCoord.xy * 2.0 - u_resolution.xy) / u_resolution.y;
|
||||
// Current pixel coordinate in 0..1
|
||||
vec2 st = gl_FragCoord.xy / u_resolution.xy;
|
||||
st.x *= u_resolution.x / u_resolution.y; // Aspect ratio correction
|
||||
|
||||
// Auto zoom
|
||||
float zoom = 1.0 + sin(u_time * 0.1) * 0.5;
|
||||
zoom = pow(zoom, 4.0);
|
||||
vec2 c = uv / zoom - vec2(0.74364388703, 0.13182590421); // Zoom into a specific interesting point
|
||||
// Map to Mandelbrot space using Zoom and Center
|
||||
// Default (Zoom 1): -2.5 to 1.5 X, -1.5 to 1.5 Y approx?
|
||||
// Let's say center is 0,0. Range -2..2.
|
||||
// st is 0..AspectRatio (approx 0..1.7)
|
||||
|
||||
// Center the coords:
|
||||
vec2 c_uv = (gl_FragCoord.xy - u_resolution.xy * 0.5) / u_resolution.y;
|
||||
|
||||
// Apply Zoom and Pan
|
||||
vec2 c = (c_uv / u_zoom) + u_center;
|
||||
|
||||
// Mandelbrot iteration
|
||||
vec2 z = vec2(0.0);
|
||||
float iter = 0.0;
|
||||
float max_iter = 100.0;
|
||||
float max_iter = 100.0 + log(u_zoom) * 20.0; // Increase details with zoom
|
||||
|
||||
for (float i = 0.0; i < 100.0; i++) {
|
||||
z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
|
||||
if (length(z) > 4.0) break;
|
||||
iter += 1.0;
|
||||
for (float i = 0.0; i < 500.0; i++) {
|
||||
if (i > max_iter) break;
|
||||
// Z = Z^2 + C
|
||||
float x = (z.x * z.x - z.y * z.y) + c.x;
|
||||
float y = (z.y * z.x + z.x * z.y) + c.y;
|
||||
|
||||
if ((x * x + y * y) > 4.0) {
|
||||
iter = i;
|
||||
break;
|
||||
}
|
||||
z.x = x;
|
||||
z.y = y;
|
||||
}
|
||||
|
||||
float f = iter / max_iter;
|
||||
vec3 col = vec3(f);
|
||||
col = 0.5 + 0.5 * cos(3.0 + f * 10.0 + vec3(0.0, 0.6, 1.0));
|
||||
|
||||
if (iter >= 99.0) col = vec3(0.0);
|
||||
|
||||
gl_FragColor = vec4(col, 1.0);
|
||||
// Coloring
|
||||
float t = iter / max_iter;
|
||||
if (iter == 0.0) {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
} else {
|
||||
gl_FragColor = vec4(
|
||||
sqrt(t),
|
||||
t * t,
|
||||
sin(t * 3.1415),
|
||||
1.0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
77
shaders/reaction.frag
Normal file
77
shaders/reaction.frag
Normal file
@@ -0,0 +1,77 @@
|
||||
#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);
|
||||
}
|
||||
Reference in New Issue
Block a user