// 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)

Streamflow can carry Whitewater FX as a separate secondary particle payload alongside the primary water points. These particles represent spray, foam, bubbles, and aerated whitewater as a visual layer; they are generated one-way from the behavior of the water, using signals such as velocity, impact, approximate turbulence, surface proximity, and splash zones.

The primary FLIP/APIC particles remain the only real water mass. They are the particles that participate in P2G, G2P, pressure, viscosity, reseeding, density correction, the primary cache, and Meshify. Secondary whitewater particles do not return forces or volume to the solver, do not enter pressure, do not change the real water count, and never become blobs in the generated mesh.

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

In real time, Streamflow uses SNP5 / wire v6 to send a separated secondary payload with position, type, normalized age, radius, flags, and ID. Blender decodes that payload and displays the points colored by type: primary water in blue/cyan, spray in white, foam in cream, and bubbles in light cyan.

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 render review or later loading, Undine writes a separate secondary cache at <run>/whitewater/frame_XXXXXX.gpfb, distinct from the primary <run>/particles/ cache. The whitewater cache stores position, velocity, radius, age, lifetime, kind, and id attributes.

Blender can load the cache as persistent separate objects named Undine_Whitewater_Spray, Undine_Whitewater_Foam, and Undine_Whitewater_Bubbles, reusing objects and materials instead of recreating them per frame.

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

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.