Skip to content

Gallery & Showcase

A glimpse of what agentwood produces — full-quality stills, and short sample clips with the exact code that made them.

Stills vs. clips

The stills below are full-resolution Cycles / eevee renders, so they show the real quality. The video clips are fast low-res proxies (that's the iteration mode) — they're here to show motion and audio, not final fidelity.


Sample scene — "Every Spring"

A complete ~10-second beat assembled from the feature set — blocking, dialogue (TTS), camera moves, HDR daylight lighting, and an ffmpeg edit — set in the flower garden. Rendered in fast mode with the Cycles engine. Unmute to hear the dialogue.

Dialogue + a soft piano bed (bgm/classical_piano) under the whole scene.

The exact same cut — same shots, dialogue, fades, letterbox — with the music layer removed.

About the music level

BGM is mixed under the dialogue. Because add_bgm blends with amix (which scales inputs), the music volume is raised to compensate — see Editing → Background music and Known Issues #11. The only difference between the two tabs is that music layer.

Source: test_check/samples/scene2_shots.py renders the four shots; scene2_edit.py (with music) and scene2_edit_nobgm.py (without) assemble them. Two choices make it work: lighting("hdr", …) lights the whole garden like daytime (placed presets only light the actor), and output_fps = animation_fps / frame_step (here 8 = 24/3) keeps the fast proxy playing continuously instead of freezing.

Built shot by shot

Shot 1 — Pergola (establishing). They meet face-to-face; gentle push-in. "You kept the garden."

shot 1

with flower_garden.Pergola.C1 as s1:
    s1.block(face_to_face(), mara, sam)
    s1.lighting("hdr", hdr="suburban_garden_2k", strength=1.3)   # daylight
    s1.camera("push", mode="medium", R1=4.2, R2=3.2, theta=20)
    mara.say("You kept the garden.", action_name="talking")
    sam.idle()
    s1.clip(3.0)

Shot 2 — Among the flowers (closeup). "Planted them the spring you left."

shot 2

with flower_garden.Flower_Garden.B1 as s2:
    s2.add(sam)
    s2.lighting("hdr", hdr="suburban_garden_2k", strength=1.3)
    s2.camera("static", mode="closeup", R=1.2, theta=-12, phi=2)
    sam.say("Planted them the spring you left.", action_name="talking")
    s2.clip(3.0)

Shot 3 — Reverse closeup. "You waited?"

shot 3

with flower_garden.Flower_Garden.B2 as s3:
    s3.add(mara)
    s3.lighting("hdr", hdr="suburban_garden_2k", strength=1.3)
    s3.camera("static", mode="closeup", R=1.2, theta=12, phi=2)
    mara.say("You waited?", action_name="talking")
    s3.clip(2.6)

Shot 4 — Seating area (resolution). Together; push-OUT to a wide. "Every spring, Mara."

shot 4

with flower_garden.Middle_Seating_area.A1 as s4:
    s4.block(shoulder_to_shoulder(), sam, mara)
    s4.lighting("hdr", hdr="suburban_garden_2k", strength=1.3)
    s4.camera("push", mode="medium", R1=2.4, R2=5.0, theta=18, phi=6)   # pull back
    sam.say("Every spring, Mara.", action_name="talking")
    mara.idle()
    s4.clip(3.2)

Merging the shots

The four rendered shots are cut together with a fade-in, three crossfades, a fade-out, soft piano, and 2.35 letterbox — pure ffmpeg (no Blender):

edit = Edit("scene2", output_root="test_check_renders/samples")
with edit.clip(".../scene2/shot1.mp4", name="a") as c: c.fade_in(0.5)
with edit.clip(".../scene2/shot2.mp4", name="b") as c: pass
with edit.clip(".../scene2/shot3.mp4", name="c") as c: pass
with edit.clip(".../scene2/shot4.mp4", name="d") as c: c.fade_out(0.6)
edit.between("a", "b").crossfade(0.4)
edit.between("b", "c").crossfade(0.4)
edit.between("c", "d").crossfade(0.4)
edit.music("bgm/classical_piano", volume=0.7)   # raised: amix halves inputs in the mix
edit.letterbox("2.35")
edit.save("scene_final.mp4")

HDR environment lighting (Cycles)

A single shot.lighting("hdr", …) call lights the actor with a real-world environment map and uses the .exr as the backdrop.

HDR — suburban garden

with bare_scene as shot:
    shot.add(hero, at=(0, 0, 0))
    shot.lighting("hdr", hdr="suburban_garden_2k", strength=1.0)
    shot.camera("static", mode="medium", R=2.5, theta=20, phi=5)

Lighting presets (Cycles, full resolution)

The six portrait presets, path-traced — notice the directional modelling on the face.

rembrandt three-point butterfly
rembrandt three_point butterfly
split silhouette spotlight
split silhouette spotlight

In a real set

The same DSL, rendered inside the canal_bridge set with full geometry.

medium shot in the set wide establishing
set medium set wide

Sample clips (code → output)

Dialog with a generated voice

say() synthesizes per-character speech and muxes it into the clip. Unmute to hear it.

detective = brian("Detective Hayes")
with bare_scene as shot:
    shot.add(detective, at=(0, 0, 0))
    detective.say("We need to talk. Right now.", action_name="talking")
    shot.camera("static", mode="medium", R=2.5, theta=12)

A camera push (motion)

The camera dollies in from far to close while framing stays locked.

with bare_scene as shot:
    shot.add(hero, at=(0, 0, 0)); shot.mark_actor_has_action(hero)
    hero.actor.idle()
    shot.camera("push", mode="medium", R1=5.0, R2=1.6)
    shot.clip(2.0)

Tracking a walk across the set

An actor walks the canal bridge; a tracking_moving camera follows.

with canal_bridge as shot:
    sam = brian("Sam")
    shot.add(sam, at=canal_bridge.Canal_Bridge1_North_End.D1)
    sam.walk_to(canal_bridge.Canal_Bridge3_South_End.F1)
    shot.camera("tracking_moving", mode="medium", R=4.0)
    shot.clip(5.0)

An assembled edit (music + letterbox)

Three shots cut together with transitions, a color look, background music, and 2.35 letterbox — all in ffmpeg, no Blender.

edit = Edit("bridge_cut")
with edit.clip(s1.render, name="a") as c: c.fade_in(0.3); c.look("cold")
with edit.clip(s2.render, name="b") as c: c.slow_motion(0.6)
with edit.clip(s3.render, name="c") as c: c.fade_out(0.3)
edit.between("a", "b").crossfade(0.4)
edit.between("b", "c").fade_to_black(0.4)
edit.music("bgm/action_heroic", volume=1.3)   # raised so it carries (amix halves; no dialogue here)
edit.letterbox("2.35")
edit.save("final.mp4")