Interactive Fluid
A compact pressure-projected fluid solver with velocity advection, colorful dye, and pointer or touch stirring.
import { Grid, index_of } from "./fluid-common.wgsl";
@group(0) @binding(0) var<uniform> grid: Grid;
@group(0) @binding(1) var<storage, read> src: array<vec2f>;
@group(0) @binding(2) var<storage, read> pressure: array<f32>;
@group(0) @binding(3) var<storage, read_write> dst: array<vec2f>;
@compute @workgroup_size(8,8) fn main(@builtin(global_invocation_id) id:vec3u){
if(any(id.xy>=grid.size)){return;} let p=vec2i(id.xy); let last=vec2i(grid.size)-1; let c=pressure[index_of(p,grid.size)];
let l=select(pressure[index_of(p-vec2i(1,0),grid.size)],c,p.x==0); let r=select(pressure[index_of(p+vec2i(1,0),grid.size)],c,p.x==last.x);
let b=select(pressure[index_of(p-vec2i(0,1),grid.size)],c,p.y==0); let t=select(pressure[index_of(p+vec2i(0,1),grid.size)],c,p.y==last.y);
var u=src[index_of(p,grid.size)]-vec2f((r-l)*.5*f32(grid.size.x),(t-b)*.5*f32(grid.size.y));
if(p.x==0&&u.x<0.0){u.x=0.0;} if(p.x==last.x&&u.x>0.0){u.x=0.0;} if(p.y==0&&u.y<0.0){u.y=0.0;} if(p.y==last.y&&u.y>0.0){u.y=0.0;}
let s=length(u); if(s>2.5){u*=2.5/s;} dst[index_of(p,grid.size)]=u;
}