// undine docs

Undine Docs

Undine is a CUDA-accelerated fluid solver for Blender, written in C++20 and CUDA 12. It is built around live iteration: preview FLIP simulations several times per second, inspect solver stability while they run, and commit to caching only when the motion feels right.

This documentation covers how it's built, how to drive it from the addon, what every parameter does, and how to diagnose a scene when something doesn't add up — without ever opening the C++ source.

What Undine is

A particle-based liquid solver for Blender — FLIP/PIC/APIC for Newtonian and viscous liquids, with production-oriented Bingham and Herschel-Bulkley rheology presets (honey, chocolate, slime). Accelerated on GPU through CUDA, shipped as a Blender addon.

The numerical core is C++20 compiled out-of-process. The Python addon handles UI, syncs the scene to the solver, drives Streamflow (live preview), and runs the deferred meshing step.

Whitewater FX (Beta) adds one-way secondary particles for spray, foam, bubbles, and aerated whitewater. They enrich impacts, wakes, waterfalls, and splash zones without changing the primary water mass or Meshify surface.

Undine is not a wrapper around Mantaflow or any external library. It's a custom solver designed to accelerate the GPU-resident fast path for water and lighter fluids, with explicit logged fallback routes to host-authoritative or implicit methods when production viscosity and rheology demand it. The design surfaces the numerics that decide whether a sim is going to hold or collapse.

Architecture, in one sentence

Staged GPU pipeline: P2G → pressure (PCG, optional V-cycle multigrid, P2G density correction) → G2P → SDF collisions → vorticity confinement → deferred meshing. Particle state lives on device between frames; Streamflow streams it back to the viewport without ever leaving the device until you ask for the mesh.

The addon never reads particle buffers from the main loop. It dispatches work through a runtime contract that locks the resolved preset, collects scalar metrics, and pulls the mesh out only when explicitly requested.

Solver stages

  • P2G — particle → grid transfer (affine APIC, velocity + affine momentum matrix)
  • Pressure projection — PCG, optional V-cycle multigrid (Jacobi or symmetric red-black GS), density correction on device, FP32 tolerance floor scaled by √N
  • G2P — back to the Lagrangian system, configurable FLIP / PIC blend per scene
  • Collisions — baked or animated SDF, configurable band, multi-collider, contact refill, CUDA-accelerated bake (LBVH, slab-based, dodges Windows TDR)
  • Vorticity confinement — Fedkiw 2001, two-pass grid op, recovers small-scale curl lost to numerical diffusion
  • Whitewater FX (Beta) — one-way secondary spray, foam, bubbles, and aerated whitewater payloads generated from primary water behavior
  • Sparse Bricks — active simulation regions tracked with halo, capability inventory, demotion-aware authority state
  • Deferred meshing — VDB-SDF or DENSITY_MC scalar route, anisotropic kernel, Taubin smoothing, native Alembic with per-vertex .velocities

Why it matters

Each stage exposes real metrics (CFL, residual, divergence, active cells, brick state, retry chain step) and can be isolated for debugging. If a scene blows up, you know exactly which stage owns it.

Version-to-version changes happen one stage at a time without touching the rest, so the solver can evolve — new preconditioners, new transfer schemes, new constitutive laws — without breaking existing scenes.

Substep retry chain

When pressure breaks down (max iters reached, NaN, FP32 plateau), the solver doesn't crash and it doesn't silently produce garbage. It promotes the substep through a deterministic chain: iterate again with relaxed tolerance → fall to FP64 → escalate to multigrid → drop to CPU. The chain is logged. The decision is reproducible.

This is why a sim that 'almost works' on another solver tends to actually finish on Undine: the unstable substep gets handled, and the rest of the bake doesn't pay for it.

What you'll find here

Concepts

Minimum vocabulary for the addon (domain, emitter, collider, playback, meshify) and how the solver stages fit together. Start with Basic Concepts if you've never touched a particle-based solver.

Workflow

The actual order a shot gets built in: tag objects, run, playback, mesh. Quick Start is the condensed version; Workflow is the per-panel breakdown.

Parameters reference

Every control in the addon, what it does, and when to push it up or down. Organized by panel (Objects, Actions, Sim Params, Meshify, Debug).

Solver Architecture

How the solver is split internally, what runs on CPU vs GPU, and why some decisions are the way they are.

Troubleshooting

Concrete symptoms (blow-ups, chaotic dispersion, fluid passing through colliders, FPS dropouts) → likely cause → fix. Read this before filing an issue.

Philosophy

Undine assumes the artist needs to iterate — not wait. Every design decision gets measured against one question: does this shorten the test cycle?

That's why the pipeline is GPU-resident, why the Debug panel exposes numbers instead of hiding them, and why presets are tuned to start fast and refine later.

It's not built only for artists who don't want to touch anything, nor only for engineers who want to tune everything. It's built for both, and the docs are organized with that in mind: use the presets when you're in a hurry, read the metrics when you're serious.

The technical-artistic premise: a fluid is a numerical system before it's a visual one. The faster you can read the numbers, the faster the visuals stop fighting you.