Files
2026-01-13 19:47:59 +00:00

67 lines
1.9 KiB
GLSL

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