Skip to content

Frame interpolation (heuristic in-betweens)

Generate N intermediate frames between two existing frames. Each in-between is a Bayer-dithered cross-fade — pixels appear / disappear via threshold, never by anti-aliasing. The result preserves the pixel-art look and gives you a coherent starting point that you can clean up by hand.

This is intended as a head start, not a finished tween. The heuristic doesn't understand motion, anatomy, or timing — for high-quality animation you'll always want to refine the result manually.


Where to find it

Frames timeline → Sparkles icon (rightmost button in the header).

Sparkles button to open Interpolate dialog


How it works

For each pixel (x, y) and each in-between frame i (1 to count):

  1. Compute the parameter t = i / (count + 1) — a value between 0 (frame A) and 1 (frame B).
  2. If t > threshold(x, y) (Bayer pattern of your choice), pick the pixel from frame B.
  3. Otherwise, pick from frame A.

The cumulative effect: the in-between at t = 0.25 shows ~25% of B's pixels distributed via the dither pattern, with the rest being A. By t = 0.75, B dominates.

For each in-between, layers are matched by name between the two source frames. If a layer name only exists on one side, the other side is treated as transparent for that layer.


The dialog

Interpolate dialog

ControlWhat
FromSource frame A (defaults to the active frame).
ToSource frame B (defaults to the next frame after active).
In-between framesSlider 1–16.
Dither patternBayer 2×2 (chunky), Bayer 4×4 (recommended), Bayer 8×8 (smooth), Solid (no dither, abrupt cut at t=0.5).

Click Generate to commit. The new frames are inserted right after the From frame in frameOrder with names like Frame A → Frame B (i/n).


What gets generated

Each new frame:

  • Has its own independent layer set (no link keys)
  • Inherits layer metadata (visibility, lock, opacity, blend mode, group membership) from the From frame
  • Inherits durationMs from the From frame
  • Inherits groups from the From frame (cloned)

If a layer name exists in From but not To (or vice versa), that layer's tween fades against transparency.


Frame tags adjust automatically

Tags whose range overlaps the insertion point grow to include the new frames; tags fully after the insertion shift forward. See Frame tags.


Patterns and when to use which

  • Bayer 4×4 (default) — best general-purpose; the dither at half-step looks natural for most sprite-scale work.
  • Bayer 2×2 — chunkier, more visible pattern. Good for very small canvases (16×16, 32×32).
  • Bayer 8×8 — smoother distribution. Good for larger canvases (128×128+) where 2×2 looks too coarse.
  • Solid — no dither at all; the in-between switches abruptly at t = 0.5. Useful as a mathematical baseline; rarely what you want artistically.

Workflow

  1. Animate two keyframes by hand — the start and end of a motion.
  2. Open Interpolate, choose count = 2 or 3 (depending on motion speed).
  3. Generate. Now you have a sequence with rough in-betweens.
  4. Clean up each generated frame by hand — re-paint anything that looks confused, smooth out the dither artefacts, fix anatomical issues.
  5. Optionally, re-interpolate between cleaned-up frames for finer subdivision.

Interpolation inserts the new frames into the global frame order but does not auto-enrol them into the active sprite (unlike plain "Add frame" / "Duplicate frame", which do). If you generated in-betweens while filtering to a sprite, switch the timeline to All frames, then drag the dimmed new frames onto a sprite frame — or right-click them and choose "Add to ". See Frames timeline.

Why use it? — concrete examples

🎬 Smooth sprite transitions you'd otherwise paint pixel-by-pixel

You drew a character with their arm down in Frame 1 and arm up in Frame 2. The transition needs 2 in-between poses (arm at 33% and 66%). You could:

  • Without interpolation — duplicate Frame 1, manually paint the arm at the intermediate angle (5–10 minutes per frame, easy to misjudge angles).
  • With interpolation — open the dialog, From=1, To=2, count=2. Click Generate. You get two frames where the arm pixels are partly the "down" position and partly the "up" position, mixed via Bayer dither. The result isn't perfect, but the silhouettes show you exactly where the arm should be at each step. Then you clean up — usually 1–2 minutes per frame instead of 5–10.

💧 Fading effects (appear / disappear)

A simple but useful case: a sprite that fades in.

  1. Frame 1: empty (or transparent layer)
  2. Frame N: the fully painted sprite

Generate N−2 in-betweens. Each one is a Bayer-dithered partial-opacity version of the sprite — a classic 16-bit-style fade-in that doesn't use anti-aliasing.

This is one place where you can often use the result as-is, no cleanup needed, because the dither pattern IS the intended look.

🔥 Particle / VFX bridges

Smoke clouds, fire flickers, magic glints often have lots of similar-but-shifted frames. You can:

  1. Paint the keyframes (clear "before" and "after" shapes).
  2. Generate 2-3 in-betweens.
  3. Lightly clean up to taste.

The dither distribution gives you a starting point that already has visual continuity.

When interpolation isn't the right tool

  • For motion that requires understanding (a hand opening into a fist, a character turning their head). The heuristic is dumb pixel cross-fade — it doesn't know about anatomy. Use it as a rough spatial guide and expect heavy cleanup.
  • For 1-frame transitions. Just paint it by hand; the overhead of opening the dialog beats the benefit at count=1.
  • For long sequences where you want each in-between to be intentional. 8+ generated frames is usually too many — the result needs more cleanup work than just animating manually.

Quick test

Paint a colour-filled rectangle on Frame 1. Move it 10 px to the right on Frame 2. Generate 3 in-betweens at Bayer 4×4. Open the Preview Window — you'll see the rectangle "slide" via dithered intermediates. Tweak the count or pattern and regenerate to compare.


Limitations

  • No motion estimation. The heuristic doesn't know that pixels move; it just blends them. A character walking will get strange in-betweens that need manual fixing — but the dither pattern at least gives you a reasonable visual outline of where pixels need to be.
  • Layer names matter. Pair-by-name matching means renaming a layer between frames will break the pairing. Keep names consistent.
  • Transparency-aware but not selection-aware. Tweens always run on the whole frame.

Tips

  • The result is most useful when frames A and B share most of their pixels and only differ in a small region.
  • Plan your keyframes so the difference is localised — a character's head moves by 2 px, the body stays put. The dither only happens where pixels disagree.
  • Don't generate too many in-betweens at once. 1–3 is usually right; 8+ creates a lot of cleanup work.
  • After cleanup, you can select the new frames into a sprite or an animation.

Motestack is a personal hobby project. The editor and these docs ship under no warranty — back up your `.mstack` files.