seededFieldInit
A field that starts full: seed it from a pass function, then run the solve silently warm.steps times so the first visible frame already flows.
seededFieldInit<TParams>(opts: {
kernel: FluidKernel
/** The value whose change forces a re-seed. */
seed: (f: FluidFrame) => number
warm: {
/** How many silent solves to run. */
steps: number
jacobiIters: number
/** Simulated seconds per warm step. */
dt: number
/** Where the warm clock starts. Randomize it so two instances differ. */
startTime: () => number
/** The full values for a warm step at simulated time `t`. `t = 0` is the seed write. */
values: (t: number, f: FluidFrame) => TParams
}
}): FluidInitPart<TParams>
Import sim from shaders/std and use sim.fluids.seededFieldInit.
Re-seeds whenever seed returns a new value. Each warm step advances a private clock by warm.dt seconds and writes warm.values(t). When it finishes, the simulation's clock continues from where the warm-up ended.
Parameters
| Name | Type | Notes |
|---|---|---|
opts | `{ |
kernel: FluidKernel
/** The value whose change forces a re-seed. */
seed: (f: FluidFrame) => number
warm: {
/** How many silent solves to run. */
steps: number
jacobiIters: number
/** Simulated seconds per warm step. */
dt: number
/** Where the warm clock starts. Randomize it so two instances differ. */
startTime: () => number
/** The full values for a warm step at simulated time `t`. `t = 0` is the seed write. */
values: (t: number, f: FluidFrame) => TParams
}
}` | |
Example
init: seededFieldInit({kernel: initKernel, seed: (f) => f.num('seed', 0), warm: {steps: 50, jacobiIters: 10, dt: 0.033, startTime: () => Math.random() * 100, values: (t, f) => ({...baseValues(f), time: t})}})
Tip. A random
startTimemakes two instances of the same layer drift differently.
See also
fluidSim— A fluid the engine solves every frame.ambientForce— A force applied to the whole field before every solve: a turbulence field, a steady wind.