§ 3.03
← studies·R&D study · 2026·Houdini · Simulation · Geomorphology

Meandering river — oxbows from neck cutoffs

A Houdini simulation in which a single curve develops into a meandering river over many frames. Each frame a curvature signal pushes the channel sideways; oxbow lakes appear when two stretches drift close enough that a shortcut edge bridges the neck and the channel crosses it, leaving the abandoned arc behind. The same step that updates the channel produces the topology change.

// 1 · intuition

Real rivers bend through a short feedback loop:

The simulation translates that loop into geometry. A curvature signal picks the direction every point on the curve should be pushed, and a small set of topology rules handles the cut-offs at the right moment.

// 2 · approach
Houdini network — meandering-river solver
Houdini network — meandering-river solver

Pipeline:

init curve  ──►  per-frame solver  ──►  river + accumulated oxbows

Initial curve

A straight line, evenly resampled, with a few layers of noise displacement applied across the middle. The displacement weight tapers to zero at both ends so the endpoints stay anchored from the start. This wobbled line is the seed the solver evolves from.

Each solver step

Compute the offset direction. The signed mean curvature of the current channel is measured and combined with the local tangent into a per-point displacement vector — a lateral push with a small downstream component. The push is again weighted to zero at the endpoints, so the channel only moves in its interior.

Push and reconnect. The displacement is added to each point. Nearby point pairs are then connected with shortcut edges, but only when they sit within a small search radius and their tangents are close to parallel. The parallel-tangent condition keeps the connection step local; without it, distant points across the canvas can also fall within the radius and get wired together.

Re-trace the channel. The channel is re-traced from start to end through the augmented graph. Where a shortcut edge bridges a neck, the trace crosses it instead of following the loop the long way around.

The same re-tracing step that updates the channel also separates the oxbow from it, so the topology change happens as part of the ordinary update.

Smooth and pin. A few rounds of blur and smooth keep the channel readable. A final pass identifies the channel's two endpoints by neighbour count — a real endpoint has exactly one neighbour — and locks them back to their initial positions. Oxbows are closed loops, so they have no one-neighbour points and stay out of this pass.

Old oxbows accumulate in the output, so a long run shows the river drifting across the canvas with the previous channels visible behind it.

The same network annotated — displace curve, cut & reconnect, oxbow
The same network annotated — displace curve, cut & reconnect, oxbow
// 3 · properties
// 4 · side experiment · closed loops

I tried the same approach on a closed curve — a ring-shaped river with no start and no end. Mixed result:

A working closed-loop version would need three different pieces: an arc-length-integrated upstream curvature signal (a simplified Howard–Knutson), Taubin smoothing in place of plain Laplacian so the ring doesn't contract toward its centroid, and a graph-theoretic ring-splitting routine in place of the start-to-end re-trace. That is a separate project.

// 5 · process · 7 images
Shading network — look-dev
Shading network — look-dev
← back to studies