Skip to content

ChrisWoody/FluidSim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FluidSim

A real-time interactive fluid dynamics simulation running entirely in the browser. Move your mouse or touch the screen to inject colourful dye into a GPU-driven fluid, creating swirling vortices and turbulence that gradually settle to rest.

This is a basic spike/stripped-back version heavily inspired by Pavel Dobryakov's WebGL Fluid Simulation — definitely check out the original as it is very good and has many more features.

WebGL No Dependencies License

How It Works

The simulation solves an approximation of the Navier-Stokes equations on the GPU using WebGL fragment shaders. Each frame runs a multi-step pipeline:

  1. Curl — compute the curl of the velocity field
  2. Vorticity Confinement — amplify small-scale rotational detail that numerical dissipation would otherwise destroy
  3. Advection — move the velocity field through itself (self-advection)
  4. Divergence — calculate how much fluid is expanding/compressing at each point
  5. Pressure Solve — iteratively solve for pressure using Jacobi iteration (30 iterations per frame)
  6. Gradient Subtraction — subtract the pressure gradient from velocity to enforce incompressibility
  7. Dye Advection — carry the visible colour field along with the velocity

User interaction (mouse/touch) injects velocity impulses and randomly coloured dye via a Gaussian splat into the simulation fields.

Tech Stack

  • Plain HTML/CSS/JS — no build step, no frameworks, no dependencies
  • WebGL 1.0 with OES_texture_half_float / OES_texture_float extensions
  • GLSL fragment shaders loaded at runtime via fetch()
  • Double-buffered framebuffer objects (ping-pong) for read/write separation

Project Structure

FluidSim/
├── index.html              # Minimal page with a full-screen <canvas>
├── css/
│   └── style.css           # Full-bleed canvas, no scrollbars, touch-action: none
├── js/
│   └── fluid.js            # WebGL setup, shader compilation, input handling, render loop
└── shaders/
    ├── baseVertex.vert     # Shared full-screen quad vertex shader
    ├── advection.frag      # Advects velocity & dye fields
    ├── curl.frag           # Computes velocity curl
    ├── vorticity.frag      # Vorticity confinement force
    ├── splat.frag          # Injects colour + velocity at interaction point
    ├── divergence.frag     # Computes velocity divergence
    ├── pressure.frag       # Jacobi pressure solve iteration
    ├── gradient.frag       # Subtracts pressure gradient from velocity
    └── display.frag        # Final output / colour mapping

Getting Started

No build or install required. Serve the files with any static HTTP server:

# Python
python -m http.server 8000

# Node.js (npx)
npx serve .

Then open http://localhost:8000 in a modern browser and move your mouse over the canvas.

Note: The files must be served over HTTP(S) — opening index.html directly via file:// will not work because the shaders are loaded with fetch().

Configuration

Key constants at the top of js/fluid.js:

Constant Default Description
SIM_RESOLUTION 256 Simulation grid size (velocity/pressure)
DYE_RESOLUTION 1024 Dye field resolution (visual output)
SPLAT_RADIUS 0.25 Size of each colour/velocity injection
SPLAT_FORCE 4000 Strength of velocity impulse on interaction
VISCOSITY 0.8 Rate at which velocity dissipates
PRESSURE_ITERATIONS 30 Jacobi solver iterations per frame
CURL_STRENGTH 20 Vorticity confinement intensity

Browser Support

Modern evergreen browsers on desktop and mobile (Chrome, Firefox, Safari, Edge). Requires WebGL 1.0 with float texture support. The canvas honours devicePixelRatio (capped at 2×) for crisp HiDPI rendering.

License

MIT

About

Built from a basic prompt, heavily inspired by https://paveldogreat.github.io/WebGL-Fluid-Simulation/

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors