Geodesic Interpolate (LRW)
Interpolate along the curve, not the chord
- latent_from
- latent_to
- metric
- latent_path
Linear interpolation connects two points with a straight line. SLERP connects them with a line on a sphere. Geodesic Interpolate takes the third option: it follows the shortest path on the curved latent manifold your decoder defines. If the premise of the whole latent-riemannian-world project is that latent space isn't flat, this is the node that acts on that premise - it computes a true geodesic path between two latents and hands you the intermediate frames as a stack.
Why you'd reach for it
The pitch, straight from the author: a straight-line interpolation can pass through unstable latent regions, while a geodesic-style path gives the sampler a smoother intermediate direction. So the target use is image-to-image morphing - take two VAEEncoded latents, walk the geodesic between them, and feed the midpoints back through KSampler and VAEDecode to get a transition where the subject deforms more naturally instead of melting through mush. The pack ships a geodesic interpolation workflow example for exactly this.
Caveat before you get excited: on the WAN video side this is not the node you want. WAN's VAE can't cheaply do the pullback-metric math this relies on, so the WAN workflow uses LRW_WanGeodesicKeyframes with a VRAM-safe approximation instead. This node is the image-model, real-geometry path.
How it works
It flattens both latents, builds a GeodesicSolver around your metric, and integrates n_points intermediate frames along the geodesic. The output latent_path is a single stacked latent where the first batch item is your latent_from and the last is latent_to - n_points * B frames in total. To use one, you pull a single frame out with LRW_LatentBlend (that node's whole job is slicing this stack) or feed the whole path through a batch decode.
The inputs that matter:
latent_from,latent_to- the endpoints, same shape.metric- required, fromLRW_VAEDecoderBridgeorLRW_PullbackMetric. No metric, no geodesic; that's the whole point.n_points(default 10) - how many frames you want between the endpoints. 2–64.n_steps(default 20) - solver integration resolution. Higher is smoother and slower.step_size(default 0.05) - how far each integration step moves. If your path comes out noisy or diverges, drop it.
The comparison you should actually run
The pack ships LRW_SlerpInterpolate for a reason: it's the baseline. SLERP is the flat-space approximation everyone knows, cheap and stable, and the honest way to evaluate whether geodesic interpolation is buying you anything on your model is to render both paths from the same two latents and eyeball them side by side. On some VAEs the difference is subtle; on others the geodesic path visibly avoids the muddy middle. Don't take anyone's word for it - that comparison is three nodes and one VAEEncode away.
Install
Search comfyui-lrw-nodes in ComfyUI Manager, or git clone https://github.com/lajjadred/comfyui-lrw-nodes into ComfyUI/custom_nodes, pip install -r requirements.txt, restart. The dependency that matters is latent-riemannian-world >= 0.3.0 plus torch >= 2.4. Early versions of the pack had a node-registration bug that made things show up broken/UNKNOWN until the author pushed a fix - git pull and a full restart clears it, and don't keep two copies of the pack in custom_nodes. The license is BSL-1.1.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| latent_from | LATENT | — | |
| latent_to | LATENT | — | |
| metric | METRIC | — | |
| n_points | INT | 102–64 | — |
| n_steps | INT | 205–200 | — |
| step_size | FLOAT | 0.0500.001–1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| latent_path | LATENT | — |