A 2d navier stoke simulation wasm library stolen from AkinAguda, extended and documented. I just added some helper functions to implement it into a game. This has no visualization component even tho you may find an example here on how to do it in threejs.
wasm-pack build --target web
import initFluid, { Fluid, FluidConfig } from '../pkg/navier_wasm';
TODO: not sure about this, find out how to change/fix this
To make the original repo work i had to add await initFluid()
before doing anything else.
await initFluid();
The fluid simulation takes a grid of max (u16-2)*(u16-2)
so 251*251
todo: not 100% sure if max=256 - 4
Theres a helper function in utils.ts
to not exceed these maxes
const = [height, width] = getDisplayDimensions(h.w)
Initiate a FluidConfig with a diffusion parameter
const fluidConfig = FluidConfig.new(height, width, df);
Create fluid with a timestep parameter
fluid = Fluid.new(fluidConfig, dt);
In your animation loop add fluid.simulate()
This is the simplest form of interacting with the simulation for an example with mouse interaction and more check out the original repo it has addV
and addD
fns taking previous mouse positions into account. Just add these to your render loop as well to create continues inflow to the right.
fluid.add_density(fluid.ix(nw/2,hw/2), 100);
fluid.add_velocity(fluid.ix(nw/2,hw/2), 100,0);
To read from the simulation call
let densityValue = fluid.get_density_at_index(index);
let velocityX = fluid.get_velocity_x(index);
let velocityY = fluid.get_velocity_y(index);
Look at the original repo for a full implementation with multiple shaders. In three js the simplest visualization without GLSL would be to render lines at each cell
This could be done like this:
Install three(examples) folder
cd three && yarn
Run it yarn dev
There are two files the sink.ts
includes a shader pointMaterial
lineMaterial
and the line.ts
its like the most minimal example possible.
- [] Collisions by cell
- [] Create a middleware to pass scene elements as collisions to the simulation
- [] Fake 3D/Hill solver create hills in 2d could be done by adding a value from 0-1 to an array for the collision 1 is full blocking and 0 is not blocking
DEFAULT_TIME_STEP
aka dt
= 0.5
DEFAULT_DIFFUSION
aka df
= 0.5
Out of bound errors means you probably asked to create a simulation matrix exceeding u16*u16 = u16 use the helper function getDisplayDimensions
Real-Time Fluid Dynamics for Games by Jos Stam
Fluid Simulation SIGGRAPH 2007 Course Notes by Robert Bridson and Matthias Muller-Fischer
Gonkee's video
3Blue1Brown's video on divergence and curl
The Coding Train's video
Full credit to: AkinAguda