// undine docs

Streamflow

Streamflow is what makes Undine feel real-time. As substeps complete on the GPU, particle frames stream into Blender's playback without ever being copied back to the host until you actually need them.

It is not a 'preview render' grafted on top of a bake. The solver and the viewport share one cache, and the runtime contract guarantees that the preset you see in the panel is the preset that ran.

Streamflow modes

The Actions tab exposes a Streamflow End-Mode selector. Two modes are visible to the user; both run the full solver, the difference is what gets meshed live.

ModeWhat runs liveWhen to use
Streamflow PointsCheap point cloud streamed to viewport per frame.Iteration speed comes first. Use while finding timing, scale, emission rate, gross motion.
Mesh Every FrameLockstep meshing per frame using the Meshify-tab preset (live_high, final_hero, final_ultra, …).When the look matters — surface tension, sheet thickness, anisotropy — and you want to judge the rendered mesh, not the points.

How a frame flows

The diagram shows the lifecycle of a single Streamflow frame. The solver writes expensive points into the shared cache, the meshifier reads them, the addon publishes the result to the viewport — all without leaving the device for the simulation portion.

Streamflow per-frame lifecycle

Solver, meshifier, and viewport coordinate through one cache. Cancel is honored at any boundary.

graph LR
    Sub["Substep loop (GPU)"]
    Pts["Cache: expensive points"]
    Mesh["meshify_tool.exe"]
    Ply["PLY / Alembic"]
    View["Blender viewport"]

    Sub --> Pts
    Pts --> Mesh
    Mesh --> Ply
    Ply --> View
    Sub --> View

Runtime contract

Before any frame is dispatched, the addon resolves a runtime contract: end-mode, preset, profile, input policy, world version. The contract is asserted by the solver before it runs.

The contract is what guarantees that selecting a final preset in the Meshify tab actually applies a final preset — not a silent fallback to whatever the global preference happened to be. If the assertion fails, the run aborts cleanly with a diagnostic instead of producing a misleading result.

Contract fieldMeaningExample
end_modeWhat kind of output the run produces.STOP · STREAMFLOW · MESH_PREVIEW · MESH_FINAL
presetThe Meshify quality bucket.live_fast · live_high · final_hero · final_ultra
profileThe solver-side resolved profile.live_fast · final_hero · final_ultra
input_policyWhat the meshifier consumes.expensive_points_only · cheap_points_or_expensive
runtime_worldCache-versioning identifier.runtime_new (production paths)
tool_requiredWhether meshify_tool.exe must run.true for production presets

Whitewater FX (Beta)

Whitewater FX is separate from the main solver in the beta. It produces spray, foam, and bubbles as a one-way, disposable visual layer; it does not participate in P2G, pressure, G2P, viscosity, or primary Meshify.

The primary FLIP/APIC particles remain the only real water mass. Secondary whitewater particles are generated from the approved water behavior and do not return forces, volume, pressure changes, or surface blobs to the main simulation.

KindVisual roleMotion model
SprayAirborne droplets from impacts, jets, waterfalls, and fast wakes.Moves with inertia, falls under gravity, and dissipates by lifetime.
FoamSurface foam that floats or accumulates on wakes, turbulent borders, and impacts.Partially follows local fluid velocity to read as drag over the water sheet.
BubblesSubsurface or near-surface aeration in energetic water.Rises through buoyancy and uses a light cyan read for viewport separation.
WhitewaterThe global term for the mixture of aerated water, foam, spray, and bubbles.Appears where the fluid gains visual energy.

Secondary payload and viewport display

For viewport preview, Whitewater uses a realtime path parallel to Streamflow. It reads primary particles from GPU memory when available, stays compatible with the resident pipeline, and applies emission and transfer budgets before publishing anything to Blender.

SNP5 / wire v6 receives secondary payloads only when the payload is ready. If preview cost exceeds the budget, the path degrades by decimation or frame skip instead of blocking the main solve.

The viewport exposes independent toggles for fluid, spray, foam, and bubbles, so the artist can show or hide each layer without restarting the simulation and without changing the physics.

Secondary cache and Meshify isolation

For final quality, Whitewater has a Production Bake path after an approved particle or Streamflow cache. It writes its own versioned secondary cache at <run>/whitewater/frame_XXXXXX.gpfb, distinct from the primary <run>/particles/ cache.

The whitewater cache stores render-ready attributes such as position, velocity, radius, age, lifetime, kind, and id, so Blender can render the layer through Geometry Nodes or instancing.

Meshify is shielded to consume only the primary water cache. The whitewater/ folder, Undine_Whitewater_* objects, and secondary kind attribute are not valid primary mesh inputs, so the main liquid surface stays separate from foam, spray, and bubbles.

SNAP playback

SNAP is the viewport-update preset attached to Streamflow. It controls how aggressively Blender's playback tries to keep up with the solver as frames arrive.

Realtime Every Sim Frame attempts to display every frame the solver produces; less aggressive presets sample frames to keep the UI fluid when the solver outpaces refresh rate.

Cancel, store, replay

A Streamflow run is interruptible. Cancel stops the solver at the next safe boundary; cached frames remain valid. Store accepts a meshed result; Discard rejects it without touching the simulation cache.

This is a subtle but important property: cancelling a preview never costs you the simulation. The expensive part — the particles — stays on disk.