Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commitdd348ac6c3

README.md

flow

Fields that push things around, and the noise they are made of. Each is a field like any other: sim.force applies it to a solver's particles, attribute.set writes it onto a geometry, and a field op combines it with others. Each also compiles to the dispatch its CPU form computes, on the same lattice hash as field.noise, so a solver evaluates it on the device at every step.

A position left unwired is where each element of the domain stands: the particles a solver steps, or the points an attribute.set writes. Wire a position to sample the field somewhere else.

procgen.searchNodes("", { pack = "flow" }) lists the family and procgen.describeNode("op.<id>") describes any one of them.

Fields that push

  • field.curl — curl noise. It swirls with no sources or sinks, so what follows it eddies without bunching up or thinning out. This is how smoke, dust and sparks move in turbulent air.
  • field.vortex — turning around an axis through a centre. It is strongest at the axis and falls to half at radius.
  • field.attractor — pulls toward a centre, fading to zero at radius when one is given. A negative strength repels.

Orientation

  • field.align — the rotation turning an element's axis (+Y unless given) onto a direction, as the quaternion orient takes. An unwired direction is each element's own v, so written onto particles as orient it turns each one onto its motion. A card drawn with zero_billboard_streak then streaks along it.

Noise

  • field.worley — the distance to the nearest scattered feature point. Use it for cells, cracks, scales and stone.
  • field.simplex — smooth signed noise in [-1, 1].
local emit = g.points.grid({ countX = 1, countZ = 1 })
local src = g.op.sim.spawn({ points = emit, rate = 200, lifetime = { x = 2, y = 4 } })
local swirl = g.op.sim.force({ field = g.op.field.curl({ frequency = 0.6, amplitude = 5 }) })
-- Air rising at 2 m/s: each ember is pulled toward that velocity, which is
-- wind and drag in one.
local updraft = g.op.field.constant({ value = { x = 0, y = 2, z = 0 } })
local air = g.op.sim.force({ field = updraft, mode = "velocity", strength = 0.4 })
local embers = g.op.sim.particles({ sources = { src }, forces = { swirl, air } })
return { points = embers.points }