FilmForge Motion
绘画如同电影帧帧,无推拉摇摄,无漂移。运动来自画面内部:粒子、雾气、闪烁、热浪、光线,全在 GPU 上免费渲染。付费视频仅保留给代码无法完成的部分(真实飞行、影片高潮的变形)。本技能填充每个镜头的 motion 字段,应用 QA 修复,为渲染器导出时间线,并渲染导演签署通过的预览。
路径:scripts/、templates/ 和 config/ 是本技能内的文件夹(加载时显示的基础目录),由 ./install.sh 放置。在工作仓库的克隆中,它们位于根目录下的 tools/、templates/ 和 config/。
渲染器为 painted-film-pipeline(Python 和 GLSL;模块名称见下文)。所有像素值均为 4K (3840x2160);渲染器通过 K = W / 3840 缩放,因此 1080p 预览使用相同的数值。
步骤 1. 读取镜头
对于每个镜头:其节拍、场景的情绪和色彩脚本、重新调整时间后的长度、底下的音乐(词句、beatmap.json 中的重音)、画中已有的内容(火、海、天空、玻璃)。生命必须属于画作的世界:灰烬从画中的火堆升起;雪落在有天空的地方。
步骤 2. 选择其生命(词汇表)
| 效果 | 参数(镜头字段) | 值 |
|---|---|---|
| 飘动雾带 | fog + fogc | (强度 0..1,起始 y,全量 y,漂移速度);颜色 (r, g, b) 0..1 |
| 高光扫描 | sweep | (周期 s,带宽 px,强度,0) |
| 火光闪烁(以点为中心) | flick + fire | 振幅 (0.07 到 0.45); (x, y, 半径 px) |
| 热浪条纹 | shim | (全量 y,零值 y,0,强度) |
| 摄像机抖动 | shake | (起始 s,长度 s,振幅 px) |
| 过渡淡入/淡出 | tin, tout | ("fade" 或 "white",秒);默认为硬切 |
| 重新构图 | crop | (x0, y0, x1, y1) 单位:源像素 |
| 粒子色调 | ashc | (r, g, b) |
| 粒子 | life | 一个配方或对以下粒子系统的 lambda |
| 闪电 | bolts | 镜头内时间列表 |
| 玻璃裂纹 | crack | (起始 s,长度 s) |
粒子系统 (painted.py):ash(t, n, wind=(vx, vy), size=(min, max), alpha, seed) 用于灰烬、尘土和雪花;flakes(...) 用于大片柔软雪花;sparkles(t, n, alpha, size) 用于闪光和星星;streaks(t, n, speed) 用于雨;embers(t, n, src=(x, y), spread, rise, life) 用于从火源升起的火星。来自真实电影的配方 (film_cut.py):SNOW(n, wind),EMB(n, alpha),GLINT,RAIN,STARS(n),GOLD。完整参数含义:references/pipeline-modules.md;经测试的情绪配方:references/effects-cookbook.md。
图形 (graphics.py,overlays.py):金色丝带在音乐中绘制、摆动并收紧 (T(points, t0, draw, w));从左到右书写的文字 (W(text, t0, x, y, size));由场景自身材料形成并消散的地名 (V(...));标题终场。
步骤 3. 让音乐驱动它
graphics.Drive 测量每帧乐谱(音量和脉冲)。绽放、火星闪耀、丝带发光和文字呼吸跟随它,因此重音能使火星闪耀而无需关键帧。将过渡和抖动放在 beatmap.json 的重音上(shake 起始 = 重音时间减去镜头开始时间)。
步骤 4. 编写 motion 字段
在 shotlist.yaml 中,每个镜头(示例:Simorgh 的火森林镜头,以及 The Lantern Moth 的光束):
motion:
life: EMB(320)
flick: 0.09
fire: [1920, 1300, 2600]
shim: [2160, 300, 0, 0.8]
ashc: [0.62, 0.55, 0.5]
motion:
tin: [white, 0.4]
sweep: [3.0, 520, 0.35, 0]
life: GOLD
shake: [0.0, 0.4, 10]
不需要任何效果镜头设为 motion: none(关卡要求每个镜头都有决策)。
步骤 5. 应用 QA 修复
对于 qa.yaml 中的每个 fix:运行其调用(grade.py 中的重新着色或蓝色、补丁、镜头 crop),写入 _g 文件,用 ledger.py palette 重新测量,然后设置 done: true。匹配的调色(底版电平)和 4K 放大由渲染器自动完成。
步骤 6. 导出、渲染、查看
python3 scripts/shotlist.py export-cut shotlist.yaml --paintings art/film > code/timeline.py
将时间线作为 P_() 行打印给 film_cut.py。然后在渲染器中:
W=1920 H=1080 python film_cut.py still out/frames 6.0 12.0 24.0 # 故事重音处的静帧
python film_cut.py sheet out/sheet.jpg # 每个镜头一帧
python film_cut.py video film/preview_1080p.mp4 audio/score.wav # 带乐谱的预览
带声音观看预览。检查每个重音处的静帧。然后导演签署通过运动阶段。
何时为视频付费
仅当运动是故事核心且代码无法伪造时:飞行(Simorgh 的起飞:带速度曲线的真实片段)、高潮时的诞生或变形。在 budget.py 中计算成本(Kling 4.0:16.25 积分/5 秒 1080p,加上关键帧绘制);先绘制关键帧并通过 QA;在模型提供草稿时低价草稿,最终确定一个版本。其余一切由绘画关键姿态(poses: 2)讲述,如同动画定格姿态。
输出
- 每个镜头的
motion字段(或none) - 从 export-cut 导出的
code/timeline.py - 应用的修复(
_g文件,qa.yaml中的done: true) film/preview_1080p.mp4,重音处的静帧,每帧一帧的联络图
关卡检查清单
- 每个绘画镜头都有运动计划或
motion: none - 每个 QA 修复已应用并重新测量
- 预览带声音观看;检查每个重音处的静帧
- 签署通过
修复表
| 症状 | 修复 |
|---|---|
| 感觉像幻灯片 | 每个静止画面需要一层与场景世界相连的动态层(粒子、雾气、闪烁);按场景变换 |
| 效果像是粘贴上去的 | 使用画中的 ashc 给粒子调色;发射源位于画中光源;雾色取自天空 |
| 画面杂乱、噪点多 | 减少粒子数(n 减半),降低透明度;每场景一个效果家族 |
| 来自不同母版的镜头无法衔接 | 该底版的匹配调色偏移:检查电平;所有镜头统一调色、颗粒和暗角 |
| 效果忽略音乐 | 未使用重音:将抖动、闪耀和过渡放在 beatmap.json 的重音上 |
| 文字难以阅读 | 移入画作安静区域 (text_area),调大字号,减慢写入速度 |
参考文献
references/pipeline-modules.md:渲染器模块及每个参数references/effects-cookbook.md:每情绪场景的测试配方,来自一部完成的电影