Every clip on this page starts as video generated by AI.
LTX 2.5 (Lightricks), first-and-last-frame image-to-video: two stills and a text prompt go in, the model generates the motion between them. 1280×704, 24 fps, 145 frames (6 s). The same shot is generated many times with the same frames and prompt; only the seed changes. Later sections also redraw these takes with Stable Diffusion through Deforum.
first frame → … → last frame
S02C · nine takes of one shot, unedited. Same first frame, same last frame, same prompt, nine seeds.
These experiments started with a small edit: replacing a frame with the same frame from another version of the shot. I wanted to see how much I could change inside an image before it became another image. The tools grew through testing, watching, and giving names to what I was finding.
how the frames are reordered
I start with several versions of one shot. They share the first frame, last frame, prompt, and duration; the seed changes. I choose one as the base, then replace selected frames with frames from the other takes at the same position. Frame 34 replaces frame 34.
The pattern decides where I make the substitutions. The run mode decides how long they last. In this 48-frame example, a dot means the base take; a digit identifies the take I put in its place.
positions (48 frames)
fib .xxx.x..x....x.......x............x.............
phase:3:8:0.12 x.................x.x...............x...x.......
euclid:3:8 x.................x.................x...........
run mode
single 1.................2.3...............4...1.......
grow 1.................22333.............444411111...
Fibonacci places the substitutions close together at the beginning, then spreads them out. Euclidean and phase patterns repeat. Single replaces one frame at a time. Grow makes each substitution longer as the clip progresses, until what began as a flash can become a short shot.
the vocabulary
I call the cuts between takes aspero. Velvet averages them. Breathe moves between an average and a single take on a rhythm. Quantum uses the differences between takes to control that movement. Melt redraws frames with feedback from the previous result. Chunkforum builds movement across clips and uses cuts to reset it. The names help me work with the operations and remember how they feel.
I measure divergence: how much the takes differ at each frame. It helps locate places where a substitution may show or an average may soften the image. Quantum also uses it as a control signal. The number tells me something about the material; I still have to watch it.
Some rhythms come from Bjorklund’s Euclidean algorithm, including E(3,8), the tresillo, and E(5,8), the cinquillo. There are named clave patterns too. Phase runs two tresillos at slightly different rates so their relationship keeps shifting.
the pipeline
I use GPT to prepare shot briefs and pairs of images. The pipeline reads the original script, finds the latest image versions, and adapts a working ComfyUI generation. It changes the images, prompt, duration, seed, and output name while keeping the settings from that graph. It then waits for the renders, selects a base take using audio dynamics, makes the micro-edits, and builds a comparison grid.
python pipeline.py --shots S02D --n 8
velvet 5
average the takes. soft where they disagree
Here I average the takes. Where they line up, the image stays relatively clear. Where they differ, it softens or splits. Ramp begins with one take and gradually brings in the others. Breathe returns to one take in three frames, then opens back out over fourteen. I am testing how that change between a definite image and several overlapping images can carry a rhythm.
velvet.py --mode mean|median|ramp|breathe
mean · median · ramp · breathe = collapse on a clave clock
velvet_S02C_breathe_euclid
velvet_S02B_breathe_phase
velvet_S02D_median_8takes
velvet_S02B_ramp_13takes
velvet_S02B_mean_13takes
melt 9
re-diffuse each frame from the last. the image never resets
I made melt to work on the result of a micro-edit. It redraws each frame at partial strength and feeds the previous output into the next frame. I was looking for the continuous transformation I had worked with in my earlier Deforum films. These tests brought me closer to it. I also lost a lot of detail by rendering below the source resolution and using the tiny VAE. Returning to the source resolution, using the full VAE, and adding back high-frequency detail improved the result. The measurements help compare versions, but they do not establish that the images feel the same.
melt.py --strength 0.20 --feedback 0.58 --detail 0.85
peak/med 1.2 · spikes 0.0 · his 1.2-2.2 / 0-2.5 · sharp 46 -> 240
MELT_quantum_inverted
SHARP_detail85
SHARP_1280_detail55
MELT_promptsched
MELT_light_s0.25
MELT_light_s0.18
MELT_light_s0.12
MELT_sdxlturbo_lcmlora
S02B-base05_grow_s1_melt_s0.30_fb0.70
quantum 7
the takes time their own collapse
In quantum, the differences between takes control the edit. Where the takes agree, I keep their average; where they separate, the image moves toward one take. The inverted version does the reverse, keeping several images visible through the most unstable moments. These tests produced fewer measured discontinuities than breathe. I am interested in how the timing changes with each shot, because the material is part of what drives it. Quantum is a name for the experiment, not a claim about physics.
velvet.py --mode quantum [--invert]
S02B 69/145 · S02A 91/145 · inverted 1.4% spikes · nothing set by hand
QINV_S02E1
QINV_S02D
QINV_S02C
QINV_S02A
QUANTUM_S02A_boardwalk
QUANTUM_S02B_inverted
QUANTUM_S02B
agua 16
same swell, smooth and jagged. the two operations on one subject
Water behaves differently. Eight takes of a winter swell can overlap into a denser sea. Cutting between them can also work because there is no single performance to preserve. But the measurements become less useful: two takes of the same wave can have very little correlation in their frame-to-frame changes. I have to judge these by watching the water.
velvet.py --pool S07E*_0000*.mp4 --mode M · fib_cut.py --run grow
3 families × 8 takes · mean median breathe quantum trail + aspero · two takes of one wave correlate at 0.07
water_S07E2_trail
water_S07E2_mean
water_S07E3_aspero
water_S07E3_quantum
water_S07E3_breathe
water_S07E3_median
water_S07E3_mean
water_S07E2_aspero
water_S07E2_quantum
water_S07E2_breathe
water_S07E2_median
water_S07E1_aspero
12 of 16 · water
chunkforum 12
the cut hides the zoom reset. travel from material that never travelled
Chunkforum builds a warp across a segment, then cuts to another clip when the movement needs to reset. I wanted to test how far I could get toward continuous travel using existing footage and no new generation. Some movement and color measurements approach those of my earlier films.
chunkforum.py --rotate 1.8 --sat 3.6 --reset hold
curl 0.115 = his 0.115 · sat 143 = his 143 · no GPU
VX_slowspin
VX_vortex_velvet
VX_rot_sat_hi
CF_miranda_VELVET
CF_boardwalk_VELVET
CF_boardwalk_runaway
CF_faces_fast
CF_miranda_portrait
CF_boardwalk_travel
chunkforum_RUNAWAY_hold_s4
chunkforum_euclid-3-8_z1.022_s2
chunkforum_phase-3-8-0.12_z1.012_s1
deforum 1
FIRST=frame LAST=warp(frame). the model re-renders every link
Here I put LTX inside a feedback loop. The current image becomes the first frame, a warped version becomes the last, and the model generates the movement between them. I use the result to start the next link. New objects appear as the chain develops, while others disappear.
deforum.py --links 10 --zoom 1.10
invents structures · 977 -> 36 sharpness by link 10
boardwalk_10links_z1.10
lora 8
2.3 loras load on 2.5. they act at generation, before any edit
These are tests with 2.3 LoRAs loaded into the 2.5 workflow. They act during generation, so I need a new family of takes before I can apply the micro-edits. In these examples, transition produced a cut with a magenta wipe rather than the morph I was looking for. Restyle increased saturation without the same measured discontinuities. These are results from the tested workflows, not a guarantee that every LoRA will transfer.
lora_test.py --lora X.safetensors --trigger zhuanchang
transition = cut + wipe, 15% spikes · restyle = sat x2, 0 spikes
tr_neutral_ltx2.3-transition_s1.00
tr_sand_ltx2.3-transition_s1.00
tr_shatter_ltx2.3-transition_s1.00
tr_smoke_ltx2.3-transition_s1.00
tr_liquid_ltx2.3-transition_s1.00
restyle_852654_LTX2.3-22B_ReStyle__s1.00
crossview_LTX2.3-22B_IC-LoRA-CrossVi_s1.00
morphA_ltx2.3-transition_s1.00
faces 25
3 live + 25 cropped. hard cuts only. order reshuffles per seed
For Miranda’s sequence, I assembled moving portraits and faces cropped from group stills. I kept hard cuts and reshuffled the order with each seed. Crescendo shortens the holds from fourteen frames to one. Live gives more time to the moving portraits and uses the stills for the shorter flashes. I wanted the sequence to move through the faces without settling into a fixed order.
build_women.py --variant crescendo|live --ramp 14:1
28 women · 7-frame inserts · no pattern, no hierarchy
S02E_women_live_s5_bed
S02E_women_live_s21_blk
S02E_women_live_s8_blk
S02E_women_live_s3_blk
S02E_women_crescendo_s21
S02E_women_crescendo_s5_bed
S02E_women_crescendo_s8_blk
S02E_women_crescendo_s3_blk
S02E_women_scattered_s34_bed
S02E_women_ordered_s21_bed
S02E_women_ordered_s11_bed
S02E_women_accelerating_s12_blk
12 of 25 · outS02/sequences
S02 9
A boardwalk · B camera · C keep warm · D scar · E rupture
The Coney Island scene, assembled using the timings in my sequence plan.
build_s02.py --women live --prefer grow
26-29s
S02_full_hard_live_s15
S02_full_hard_live_s12
S02_full_hard_live_s11
S02_full_hard_ordered_s14
S02_full_hard_crescendo_s13
S02_full_hard_scattered_s9
S02_full_hard_crescendo_s7
S02_full_hard_ordered_s4
S02_full_hard_crescendo_s1
aspero 128
cut hard between takes of one shot
Aspero is the operation of the original idea: substituting frames between takes of the same shot on a rhythm. The takes share a setup (prompts. number of frames, first and last frame) but differ in their details. I use that small difference to make the image unstable from within.
pipeline.py --shots S02D --n 8
SHOT-baseNN_mode_seed · single|grow · phase:3:8:0.12
S02E8-base00010_grow_s5
S02E8-base00010_single_s5
S02E8-base00010_grow_s3
S02E8-base00010_single_s3
S02E8-base00010_grow_s2
S02E8-base00010_single_s2
S02E8-base00010_grow_s1
S02E8-base00010_single_s1
S02D-base00002_grow_s5_v2
S02D-base00002_single_s5_v2
S02D-base00002_grow_s3_v2
S02D-base00002_single_s3_v2
12 of 128 · outS02
V3Y seq 22
the frame-swap as the cut. freeze, black, silence
Earlier versions of the subway scene. Some use frame substitutions to move between shots. Another version is built around events and ends with a freeze, a cut to black and silence, then a single held frame.
seq_glitchcut.py --pattern phase:3:8:0.12 --trans 48
V3Y_repeat_build_silent
V3Y_repeat_early_vo
V3Y_repeat_build_vo
V3Y_repeat_weave_vo
V3Y_glitchcut_phase_silent
V3Y_glitchcut_phase_single_vo
V3Y_glitchcut_phase_vo
V3Y_glitchcut_grow_vo
V3Y_glitchcut_single
V3Y_glitchcut_grow
V3Y_event_origvo
V3Y_event_silent
12 of 22 · outV3Y/sequences
V3Y 50
55 takes, five shots, bases by hand
pipeline.py
Y_S01E-base07_grow_s1_srcALL
Y_S01E-base07_single_s1_srcALL
Y_S01D-base08_grow_s1_srcALL
Y_S01D-base08_single_s1_srcALL
Y_S01C-base10_grow_s1_srcALL
Y_S01C-base10_single_s1_srcALL
Y_S01B-base10_grow_s1_srcALL
Y_S01B-base10_single_s1_srcALL
Y_S01A-base11_grow_s1_srcALL
Y_S01A-base11_single_s1_srcALL
Y_S01E-base07_grow_s5_srcfib
Y_S01E-base07_single_s5_srcfib
12 of 50 · outV3Y
S01 51
where it started. fibonacci across takes
Early Fibonacci substitutions across takes of the subway shot, followed by assemblies with the ElevenLabs voiceover.
fib_cut.py
S01E_fib-grow_pick-random_s5_srcfib_bl2
S01E_fib-single_pick-random_s5_srcfib_bl2
S01E_fib-grow_pick-random_s3_srcfib_bl2
S01E_fib-single_pick-random_s3_srcfib_bl2
S01E_fib-grow_pick-random_s2_srcfib_bl2
S01E_fib-single_pick-random_s2_srcfib_bl2
S01E_fib-grow_pick-random_s1_srcfib_bl2
S01E_fib-single_pick-random_s1_srcfib_bl2
S01D-08fade_grow
S01D-08fade_single
S01D_fib-grow_pick-random_s3_srcfib_bl2
S01D_fib-single_pick-random_s3_srcfib_bl2
12 of 51 · .
archaeological software excavation
I made my 2023–24 films with AUTOMATIC1111, Deforum, and Parseq. Parseq let me score changes frame by frame using keyframes, formulas, and audio. When I moved to the RTX 5080, the old PyTorch installation could no longer run on the card. Returning to those films meant rebuilding access to the tools that made them.
Working with GPT, I copied the engine and Deforum into a separate environment with a newer PyTorch build. The first animation failed before rendering a frame. After a patch for an empty ControlNet namespace, the retry produced 48 frames. A handoff note still described the failure after the render had succeeded. I had to check the logs and the actual output to know where the work stood.
excavation 3
raw auto1111 + deforum on a 5080. dead engine, new torch
The first renders from the restored Deforum engine. A 48-frame Realistic Vision test brought back the kind of continuous change I had been looking for. Its measurements fell within the range recorded from my earlier films. ComfyUI can now launch the engine, send a job, retrieve the frames, and stop it before another model uses the GPU.
pixelsoup\deforum-app\start.ps1 -Ckpt X · Deforum Render (PixelSoup)
torch 2.7.1+cu128 · 1 patched line · 48f in 20s · 15.34 / 1.31 / 0%
01_first_render_rv_2d
02_comfy_bridge_rv
03_parseq_leonsol22_rv_3d
jam 5
his parseq scores, decoded. prompts crossfade on AND weights
I went back through eighty settings files containing Parseq data. They showed how I had been working with drifting seeds, audio-driven strength, camera movements scored against the bar, and prompts that blend over time. I tested those mechanisms separately on one still. Abrupt prompt changes lost the face early. Blended prompts held it longer while gold and leaves appeared. Seed drift reduced some changes but also led to a dotted texture. In the old scores, strength kept moving; holding it constant changed the behavior.
Parseq Score (PixelSoup) · parseq_tools.py · prompt_weights.py
80 scores · seed drift 0.0089/f · hard 14.9/1.36 · linear 13.2/1.43 · his 7.1/1.93 · pulse 7.1/1.84
A_hard
B_linear
C_his
D_pulse
compare_2x2
hyper 5
juggernaut x hyper alone in the loop becomes texture
I tested my julietest settings with an SDXL Hyper model and the leonsol22 score. The image quickly became spots and radial streaks. Changing the step count, camera, CFG, and noise did not resolve that behavior in these tests. The same score held its form better with Realistic Vision at CFG 6. I am keeping the comparison because a score that worked in one setup did not carry over cleanly to another.
checkpoint Juggernaut X Hyper · DPM++ SDE 6 · CFG 1.7 · leonsol22 score
spots from frame 1 · 2 steps / 6 steps / still camera / CFG pulse / noise 0.15 - none recover
01_leonsol_2steps
02_leonsol_6steps
03_still_camera
04_cfg_pulse
05_noise_015_fixed_seed
feed 15
feed it a video. the take becomes the structure
I use an LTX clip to guide Deforum through depth and, in some versions, edges. This gives the redraw a moving structure while the prompts change the surfaces. In the subway tests, coats become gold and foliage appears in the windows. Stronger control preserves more of the source and gives the prompts less room. Looser or pulsing control lets more transformation through. I also used the bass from Subwayseq to drive strength on every frame, then tested it on the ControlNet weights as well. The surfaces respond to the music while the figures largely keep their outlines. One apparently steady result was almost frozen, which made the limit of the measurements very clear: less frame change is not automatically better movement.
LTX take -> ControlNet Unit (depth / canny) -> Deforum Render
RV depth 22.8/1.20/0% · Jugg depth 13.4/1.10/0% · depth+canny 7.4/1.20 · looser 0.6+0.3 9.2/1.08 · release@60% 7.7/1.14 · breathing grip 9.6/1.09 · noise pulse 13.5/1.16 · trap: fixed seed 2.9 = frozen · song bass -> strength 12.7/1.64, change follows bass r=0.84 · bass -> strength + grip 12.3/1.73 r=0.86
03_S03A_jugg_depth_canny
04_S04B_jugg_depth
06_trap_fixed_seed_cadence2
07_trap_compare
08_S03A_jugg_depth_noise_pulse
09_S03A_jugg_depth06_canny03
10_S03A_jugg_release_at_60pct
11_S03A_jugg_breathing_grip
12_S03A_drawn_strength_zoom_curves
13_S03A_subwayseq_bass_strength
14_S03A_subwayseq_bass_grip
15_S03A_strength_vs_grip_compare
12 of 15 · excavation/feed
mondongo 11
everything in one pot. the take as bones, motion and skin. mueca
Mondongo combines several controls. The LTX clip supplies structure through ControlNet, motion through optical flow, and a portion of its own image through Hybrid Video. A constant 30% source blend held the wider group shots so firmly that little of the prompt came through. On the scar close-up, gold seams and stone textures could develop while the eye and gesture remained recognizable. Changing the blend let the transformation go further, but one version lost the woman’s identity. I also play the results backward. On the scar, reversing the sequence changes the reading: the marks draw together and the surface returns toward skin. That change in meaning interests me as much as the settings.
Load Video -> ControlNet Unit x2 + Hybrid Video -> Deforum Render
comp 0.3 + RAFT flow · S03A 5.3/1.23 the source wins · S02DM scar 6.2/1.66 kintsugi, then stone · breathing blend 13.0/1.50 another woman · women cuts 11.6% spikes -> 0% (8.3/1.56)
01_S03A_hybrid_comp030_flow_raft
02_S02DM_scar_mueca_kintsugi_stone
03_S02DM_scar_mueca_reversed
04_women_sequence_melt
05_women_sequence_melt_reversed
06_S02E6_ceramics_kintsugi
07_S02E6_ceramics_kintsugi_reversed
08_S02DM_scar_breathing_blend
09_S02DM_scar_breathing_blend_reversed
10_S02DM_scar_kintsugi_closer
11_S02DM_scar_kintsugi_closer_reversed
ripple 13
first frame swapped, whole clip follows. same move, other body
With Ripple, I give the model a reference clip and an edited first frame. I am testing how much of the movement it can keep while changing the image. In the professor replacement, the measured motion correspondence was much higher than between two independently generated takes. That makes another kind of micro-edit possible: cutting between versions that share more of the same movement. Repeated passes retained the measured motion in this test while gradually losing visual fidelity. It is useful for this operation; the continuous melt remains a different problem.
ripple.py --video TAKE.mp4 --first EDIT.png --say "..."
LTX25_Ripple_v11 @ 1.35 · r 0.966 vs a 0.243 two-take ceiling · chain 5 deep holds
ripO_waterWithdraws
ripO_faceInWater
ripO_faceInFoam
ripA_bw
ripE_chain5
ripE_chain4
ripE_chain3
ripE_chain2
ripD_prof
S05B_sevenfaces_grow
S05B_sevenfaces_single
S05A_manswap_grow
12 of 13 · ripple
monstruo 9
macro with no face in it. it invents one, and the one it invents is wrong
These are the tests where the image went somewhere I did not want. A close-up of skin and a brow did not give Ripple enough information to preserve the person. The movement survived, but the model invented the face revealed at the end. Enlarging a face from a group image introduced other problems: compression and sharpening became marks that looked like wounds. Those changes brought a feeling the scene did not need. I kept the failures to show where the operation stopped serving the piece.
ripple.py --video S05B_00001_.mp4 --first SCAR-MACRO-V3.png
5 scar stills → 3 strangers · camera move intact, r 0.76-0.93 · ceiling 0.888
ripO_waterPlea
ripC_scar
ripB_people
ripF_faceE1
ripS_v5
ripS_v4
ripS_v3
ripS_v2
ripS_v1
cangrejo 22
three frames forward, one frame back. one take, reordered
Cangrejo begins with one clip. I reorder its frames: three steps forward, one back. The shot advances while repeatedly pulling backward, and the result runs twice as long. Four forward and three back slows that progress much further. The effect depends on the subject. A wave can reverse without announcing it; a hand returning a bag makes the undoing visible. Salad adds other takes of the same shot, placing some backward steps in another version. I test the substitution on the back-step, once per cycle, on every frame, or at random.
cangrejo.py --pool "S07E2_*" --fwd 3 --back 1 --mix back
net +2 source frames per 4 output · x2.00 longer · 59 reversals in 239 frames
S07E3_salad_f3b1_back_t4
S07E1_salad_f3b1_back_t4
S07E2_salad_f3b1_back_t4_rev
S07E2_salad_f4b2_back_t4
S07E2_salad_f3b1_back_t8
S07E2_salad_f3b1_random_t4
S07E2_salad_f3b1_every_t4
S07E2_salad_f3b1_cycle_t4
S07E2_salad_f3b1_back_t4
S07E1_00001_f2b1
S07E1_00001_f3b1
S03E_00001_f4b2
12 of 22 · cangrejo