Power-User Systems

Smoke Field

A real-time GPU fluid you can stir — semi-Lagrangian advection, a Jacobi pressure solve, and vorticity confinement run every frame across ping-ponged float buffers, injecting a dark amethyst plume that curls, billows, and bleeds through the frame wherever you drag.

Install

bun add ogl

Then copy 2 files into your project:

  • components/registry/smoke-field/smoke-field.tsx
  • hooks/use-animation-loop.ts

Props

PropTypeDefaultDescription
dyeColorstring (hex)"#a855f7"Color of the dye injected into the fluid.
backgroundColorstring (hex)"#05010a"Background the plume rises against.
quality"low" | "medium" | "high""medium"Bundles simulation and dye buffer resolution. Higher is finer and costlier.
pressureIterationsnumber25Jacobi pressure passes per frame — higher makes the flow tighter and more incompressible.
velocityFadenumber0.98How long motion persists before it dissipates.
densityFadenumber0.97How long the dye lingers before fading out.
curlnumber20Vorticity-confinement strength — swirl detail. 0 skips the curl passes.
splatRadiusnumber0.2Size of the dye and force splat under the pointer.
splatForcenumber1Velocity impulse imparted by a pointer drag.
autoPlumebooleantrueContinuously inject a rising plume at the base when idle.
buoyancynumber1Upward force lifting the dye, so smoke rises. 0 lets it drift neutrally.
exposurenumber1.2Brightness of the rendered dye.
grainnumber0.04Animated grain over the final image.

What It Demonstrates

Drag
Moving an element by grabbing it, often with momentum when released.
Loop
An animation that repeats, a set number of times or infinitely.
Idle animation
Subtle motion that plays while an element is just sitting there, waiting to be interacted with.

Related Components

Appears In