TimeSlice ▸ Temporal Displacement
When your video's past should show up inside the frame
- images
- images
Slit-scan is the effect where a single vertical strip of a video smears across time - think the camera that stares at a runway for twenty minutes and turns it into a long streak of light. TimeSlice (display "TimeSlice ▸ Temporal Displacement") is that idea turned into a ComfyUI node, and then pushed way past its original form: instead of one slit you get hundreds of thin bands, each showing a different moment of your clip, stacked into a single frame. It's the node you reach for when a normal cut or transition feels too honest.
How it works
Feed it an IMAGE batch (frames in order). For each output frame, TimeSlice picks a spatial position on the frame, looks up a time offset for that position, and samples the input frame at current_time + offset. Bands near the anchor line sit at zero offset - they show the real present - while bands further away sample progressively earlier or later frames. The result is a smear where motion in your clip stretches into ribbons along the slice axis. It's not a blur; it's genuinely different time samples laid side by side, so a dancer's hand appears in twenty places across the frame at once.
span_frames (default 16) sets how far back/forward in time the smear reaches - bigger means more drag. band_px is the personality switch: at 1 you get smooth, continuous slit-scan; bump it to 8–32 and each band becomes a chunky constant-time strip, which reads as glitchy "banding" rather than smear. axis (vertical/horizontal) picks the slice direction, curve makes the time falloff ease instead of linear, and edge decides what happens when a band would need a frame before the start or after the end: clamp freezes the first/last frame, wrap loops, mirror bounces.
The optional knobs that turn it into a style
The fun lives in the optional inputs. pixelate_px downsamples each band into NxN blocks - that's your datamosh look. chroma_spread gives each RGB channel its own time offset, producing chromatic fringing along the smear. jitter_px adds a deterministic sideways shift per band (seeded, so it's reproducible). And cubic_px is the wild card: instead of flat bands, it lays down 2D time cubes where time flows along both axes, with cubic_lateral controlling how much of that flow goes sideways. On top of all of it, tint_mode (rainbow/thermal/ice/neon) paints a color ramp keyed to each band's time-offset, which is the difference between "datamosh" and "music video".
Wiring it
Input is images (a frame batch), output is images of the same length. Drop it between your video source and the encoder: Load Video → TimeSlice → Save Video. span_frames of 16 works best on clips that are much longer than 16 frames - the smear has to have somewhere to reach. A still image or span_frames of 0 passes through unchanged, which is handy for A/B-ing.
Install
TimeSlice is part of the unified MSCH Nodes pack. Install once via ComfyUI Manager (search "MSCH Nodes" / msch-comfyui-nodes), or:
cd ComfyUI/custom_nodes
git clone https://github.com/mariobilly/msch-comfyui-nodes.git
cd msch-comfyui-nodes
python -m pip install -r requirements.txt
then restart ComfyUI. It's pure torch tensor work with no extra models, so it won't drag anything else down.
Where people get burned
The usual mistake is feeding a clip with barely any motion and wondering why nothing happens - slit-scan is the motion, so static footage just looks like soft vertical smearing. Shoot or source footage with real movement along the slice axis. Second, watch your edge setting on short clips: with wrap, the smear pulls frames from the other end of the timeline, which can feel like a loop you didn't intend. And for the actual "ribbon of light" look, start from the defaults and only touch span_frames and band_px before you wander into time cubes - the extras are a lot easier to appreciate once the baseline effect reads clearly.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| axis | COMBO | vertical | 2 options: vertical, horizontal |
| span_frames | INT | 160–240 | Frames of time spread across the frame. Bigger = more smear. |
| band_px | INT | 11–256 | 1 = smooth slit-scan; larger = chunky constant-time bands. |
| anchor | FLOAT | 0.500–1 | Where the zero-time line sits (0=top, .5=middle, 1=bottom). |
| curve | COMBO | linear | 2 options: linear, ease |
| edge | COMBO | clamp | 3 options: clamp, wrap, mirror |
| pixelate_pxopt | INT | 00–64 | 0=off. Downsample each band into NxN blocks (datamosh). |
| jitter_pxopt | INT | 00–200 | Max random sideways shift per band (deterministic by seed). |
| jitter_seedopt | INT | 00–2147483647 | — |
| chroma_spreadopt | INT | 00–60 | Per-RGB-channel time offset. >0 = colorful chromatic fringing along the slice. |
| cubic_pxopt | INT | 00–256 | 0=off (flat bands). >0 = 2D TIME-CUBES of this size; time flows in both axes. |
| cubic_lateralopt | FLOAT | 1.00–3 | How much time also flows sideways across cubes (cubic mode only). |
| tint_modeopt | COMBO | off | 5 options: off, rainbow, thermal, ice, neon |
| tint_strengthopt | FLOAT | 0.000–1 | Blend a color ramp keyed to each band/cube's time-offset. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |