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:1080p 每 5 秒 16.25 點數,加上關鍵影格繪製);先繪製關鍵影格並通過 QA;當模型提供草稿時節省成本,最終僅定稿一個版本。其他一切都以繪製的關鍵姿勢(poses: 2)來講述,如同動畫定格一樣。
輸出
- 每個鏡頭的
motion欄位(或none) - 從 export-cut 產生的
code/timeline.py - 已套用的修復(
_g檔案,qa.yaml 中done: true) film/preview_1080p.mp4、重拍處的靜止幀、每鏡頭一幀的 sheet
閘門檢查清單
- 每個繪製的鏡頭都有動態計畫或
motion: none - 每個 QA 修復已套用並重新測量
- 預覽已含聲音觀看;每個重拍處的靜止幀已檢查
- 已批准
問題修復表
| 症狀 | 修復 |
|---|---|
| 感覺像幻燈片 | 每個定格都需要一個與其世界相關的活動層(粒子、霧氣、閃爍);按場景變化 |
| 效果像是貼上去的 | 使用畫作的 ashc 為粒子染色;發射器設在繪製的來源處;霧氣顏色取自天空 |
| 畫面雜亂、噪點多 | 減少粒子數量(n 減半),降低 alpha;每個場景只使用一種效果家族 |
| 不同世代的鏡頭無法剪接在一起 | 該圖層的匹配色調有誤:檢查色階;所有鏡頭使用同一色調、顆粒和暗角 |
| 效果忽略音樂 | 未使用重拍:將震動、爆發和轉場放在 beatmap.json 的重拍上 |
| 文字難以閱讀 | 將其移至畫作的安靜區域(text_area),調大字體,減慢書寫速度 |
參考資料
references/pipeline-modules.md:渲染器的模組與每個參數references/effects-cookbook.md:按情緒分類的經測試配方,來自一部完成的電影