Toon reel
您正在使用 toon-reel-engine 導演並製作一部短動畫故事。所有內容都是 Python:角色、場景、燈光和攝影機都是程式碼,每一幀是時間 T 的純函數。沒有時間軸編輯器和關鍵幀 UI。您編寫資料(按鍵、鏡頭表),然後檢視幀。
引擎的佈局(請保持:相對匯入依賴於此):
tools/toon/ 引擎:toon.py(渲染器)、rig.py(角色)、anim.py(時間設定)、cast/ props/ sets/(套件)
tools/ sound.py(從提示生成音軌)、mix_check.py(語音清晰度)、finish.py(-14 LUFS 匯出)、
thumb.py(封面)、find_phrases.py(旁白錄音中的詞組時間)
episodes/starter/toon 範本:「The Lamp」,12.5 秒,四個鏡頭,一個房間,一個角色。複製此範本開始。
episodes/window/toon 完整範例:「The Man at the Window」,50 秒,13 個鏡頭,兩個世界和一個轉折。
episodes/jeff, episodes/smilingman 完整範例和套件匯入的支援模組(不可執行的集數)
指令。 下面的 python 指的是已安裝 requirements.txt 的直譯器(Windows 上為 py)。
集數自己的腳本(reel.py、build_tl.py、finalize.py)從集數資料夾 episodes/<name>/toon 執行。工具從專案根目錄執行:python tools/sound.py episodes/<name>/toon。
第一步:找到或設定引擎
在個人自己的專案資料夾中工作,永遠不要在插件的安裝資料夾內(更新時會被取代)。
- 如果工作資料夾已有
tools/toon/toon.py,則使用它。 - 否則引擎隨此技能一同提供。其根目錄位於此技能基底目錄的上兩層(
<skill dir>/../..:包含tools/、episodes/、requirements.txt和.gitignore)。將這四個項目複製到工作資料夾,保持佈局,並告知使用者您已完成。如果該資料夾沒有tools/(技能被單獨複製),請改用https://github.com/wlr2/toon-reel-engine進行複製。 pip install -r requirements.txt,並確認ffmpeg -version可正常執行(5.1 或更新版本)。字幕需要 Arial Black,或設定TOON_FONT為一種粗體無襯線.ttf字型。- 在構建任何內容之前,先從
episodes/starter/toon驗證設定:執行python build_tl.py,然後python reel.py --frame 5.0必須寫入review/_f5.00.png。
順序是固定的
腳本 -> 時間軸 -> 角色造型表 + 場景幀 -> 分鏡 -> 檢查(兩輪)-> 預覽 -> 主渲染 -> 音效 -> 完成 -> 後製。
在檢查通過並記錄之前,永遠不會開始主渲染。在動畫製作之前,向使用者展示角色造型表和一個場景幀;在全解析度預覽之前,展示帶標籤的關鍵幀表。在花費任何費用(付費 TTS、付費音效、雲端渲染)之前先詢問。
1. 腳本(references/script.md)
十個步驟的方法:從最具體的矛盾開始,一個主要問題,一連串後果,每隔幾秒一個變化,為口語和動畫而寫,一個動態的中段,一個有價值的結尾(最後是招牌台詞),誠實的框架(對於 creepypasta 使用「AN INTERNET HORROR STORY」),一個計時的鏡頭表,然後進行保留編輯。如果使用者交給您一個腳本或節拍表,他們的文字和他們的規格優先於此處的任何內部規則:永遠不要改寫他們的台詞,而是建議更改並引用您要更改的內容。
交付物:SCRIPT.md(三個鉤子 + 選擇、完整旁白、計時鏡頭表、字數)和 script.py。
2. 時間軸,然後是語音
script.py包含PHRASES(每句台詞的位置、文字、字幕區塊(使用[word]表示紅色關鍵字))和MARKS(以秒為單位的故事節拍,將成為鏡頭邊界)。python build_tl.py寫入timeline.json(total、marks、lines)。短片只讀取timeline.json。 在範本中,它在任何音訊存在之前即可執行:詞組長度從字數估算,因此您可以先進行畫面分鏡。- 語音每位說話者一個錄音,48 kHz 單聲道,來自任何 TTS 或麥克風(此儲存庫不提供;ElevenLabs 是付費的,Kokoro 是免費且本機的)。永遠不要為了湊時間而加速錄音:改為剪掉一個節拍。在發送給 TTS 的文字中,將數字拼寫為單詞。
python tools/find_phrases.py take.wav會列印錄音中每個詞組的(start, end)。將它們放入PHRASES並重新執行build_tl.py:它會剪出詞組、放置它們並寫入audio/narration.wav。然後重新檢查每個鏡頭:實際詞組長度與估算不同。- 提供的
build_tl.py檔案處理一位旁白。對於多位說話者,每位說話者保留一個錄音,並將說話者加入每個詞組(對build_tl.py進行小幅修改)。 - TikTok 的髒話:在單獨的音軌中嗶掉,並在字幕中用星號標示(
f***ing)。
3. 集數檔案(references/engine.md)
| 檔案 | 工作 |
|---|---|
script.py | 台詞、字幕區塊、標記 |
build_tl.py | timeline.json(+ audio/narration.wav) |
looks.py | 角色陣容:每個造型是 rig.LOOK 中的一個字典 |
scenes.py | 世界:場景幾何、燈光、時間 T 時誰在哪裡、表演軌跡 |
reel.py | SHOTS、字幕、render(T)、檢查和渲染指令 |
cues.py | 用於 tools/sound.py 的音效事件 |
finalize.py | 混合音軌、合成到渲染、執行 tools/finish.py |
透過將 episodes/starter/toon 複製到 episodes/<name>/toon 來開始一個新的集數。其 reel.py、build_tl.py 和 finalize.py 是通用的,可以保持不變;您需要取代 script.py、looks.py、scenes.py、SHOTS 表和 cues.py。不要從 episodes/window/toon 開始:其 reel.py、cues.py 和檢查是與該故事相關聯的(兩個鏡像世界、命名標記、自訂旋轉攝影機)。閱讀它以學習技術:紋理、景深、每個世界的臉部按鍵、玻璃上的手、世界之間的交叉淡入淡出。較大的集數會將表演從 scenes.py 移到 acting.py。
一個世界需要兩個方法:draw(fr, cam, T),繪製所有內容並返回 {pid: rig.draw 結果},以及 cast(T),返回 [(pid, look, pose)]。pid 是此集數中角色的 ID(例如「nora」)。每個地點一個世界和一個時間軸;鏡頭只選擇攝影機。
4. 造型(references/look.md)
圓潤簡單的形狀、稍大的頭部、大而有表現力的眼睛、消光材質搭配柔和的 3-停止陰影以及基礎顏色中較深的輪廓線。每個角色根據腳本擁有自己獨特的輪廓、臉部和調色板(永遠不要重複使用另一個短片的角色);重複出現的角色保持設定一致性。在動畫製作之前,從 tools/toon 製作一個模型表:python -m cast.sheet ../../episodes/<name>/toon/looks.py <look>(它會在專案根目錄寫入 assets/kit/cast/<look>.png,或您作為第三個參數提供的路徑)。
5. 照明(references/lighting.md)
每個地點有三層:一個冷色環境(藍紫色夜晚保留細節),一個每個臉部上的柔和主光(從上前方,由燈具或窗戶激發),以及多個距離的暖色實用燈光,照亮它們附近的物體。臉部是畫面中最清晰的東西;背景在它們周圍稍微暗一些、對比度低一些。腳下、家具和觸碰的手下方有接觸陰影。每個地點一個燈光設定:方向、顏色和曝光在剪接之間保持不變。沒有光暈、沒有發光輪廓、沒有黑色被壓碎。天氣(雨、雪、風)在故事中有天氣的安靜時刻進行動畫。
6. 攝影機(references/camera.md)
- 每 2-3 秒一個剪接。每個鏡頭服務一個動作、一個表情或一個揭露。
- 鉤子(0-3 秒)是短片中最美麗的移動鏡頭:攝影機和角色從第一幀開始移動。
- 先雙人鏡頭,然後匹配的特寫。特寫保持在視線方向約 35 度以內。
track(a, b, ease)在兩個按鍵(position, target, focal px, horizon)之間進行一次乾淨的移動。攝影機會轉向面對目標,但不能傾斜:目標的高度被忽略。使用攝影機高度和horizon(較小的值會將視線線置於畫面中較高位置,這看起來像往下看)來向上或向下構圖。- 保持攝影機距離視野中任何人 >= 0.45 公尺:
rig.draw不會繪製比這更近的人。 - 字幕(Arial Black 66 px、白色、黑色描邊、關鍵字 #FF4D4D)永遠不會位於臉部或手上。使用
cap=(y, size)為每個鏡頭移動字幕。
7. 表演和排練(references/acting-staging.md)
每個動作都是一個帶有偏移的鏈條:眼睛 -> 頭部 -> 肩膀 -> 身體 -> 手,作為準備 -> 移動 -> 穩定。反應使用 out/snap 緩動,穩定使用 back。抓取在閉合之前先伸展。一個只轉動頭部和肩膀的角色可以站在預設腳部上;一個需要走路或轉動身體的角色需要將腳部錨定在世界空間中(從 rig.replant 或 rig.gait 取得的 ankle_R/ankle_L),一次移動一步。在進行任何分鏡之前,請先閱讀排練教訓:每一個都是已經發生過的故障。
8. 檢查:每次主渲染前的閘門(references/checks.md)
python reel.py --check-> 讀取整個review/reel_checks.txt。在範本中,每個問題都是一行ANOMALY:伸展、腳部下沉、手肘過度彎曲、手肘和膝蓋翻轉、跳動、人物離鏡頭太近、字幕覆蓋臉部或手部。python reel.py --stills-> 每個鏡頭的第一/中間/最後一幀(第一輪)。python reel.py --sheet <SHOTS>-> 在有間隔的頁面上,每個幀的接觸鏡頭、行走、轉動和遮擋變化(第二輪)。尋找分裂、肢體彈出、頭部穿過物體、物體消失。- 在資料中修正、重新執行,並將每個異常記錄在
review/LOG.md中(僅追加):時間、鏡頭、原因、修正、驗證方式;以及接受的標誌(附帶原因),以及您無法檢查的內容。 - 永遠不要僅從程式碼就聲稱「沒有異常」。程式碼檢查關節,而不是畫面:它看不到人物穿過家具或彼此、道具錯過手部、錯誤的繪製順序,或 0.8 公尺的側向移動(看起來像劈腿)。這些問題您需要在頁面上找到。
9. 渲染(從集數資料夾)
python reel.py --preview --full->review/reel_preview.mp4(1080x1920,無聲)。python finalize.py preview加入混音 ->review/preview.mp4。展示它,獲得批准。python reel.py --master-par 12->video/reel_silent.mp4:使用 12 個程序的主渲染(請使用您的核心數)。
10. 音效、混音、完成、後製(references/sound-finish.md)
cues.py,然後從專案根目錄python tools/sound.py episodes/<name>/toon-> 音樂、音效和環境音軌。真實事物的真實錄音(將 CC0 或授權樣本放入assets/sfx/);僅對抽象無人機、上升音和轟鳴聲使用合成。範本的提示都是合成的,因此鏈條可以執行:請取代它們。python tools/mix_check.py episodes/<name>/toon:語音必須在每句台詞上比背景音樂大 >= 10 dB(在有真實旁白錄音之前,每句台詞都會失敗)。python finalize.py final(集數資料夾)->tools/finish.py-> -14 LUFS、<= -2 dBTP、H.264 High、+faststart。- 封面,從專案根目錄:
python tools/thumb.py frame.png cover.jpg --line "TITLE:#F2EFE6:120"。 POST.md:每個平台的字幕、主題標籤,以及提醒在應用程式中開啟 HD 上傳。
此處使用的術語
- 標記:以秒為單位的命名故事節拍(
MARKS),用作鏡頭邊界和時間動作。 - 站位:角色站立的點(x、z、面向)以及他們移動到該點的時間。
- 錨定腳部:在世界位置固定的腳踝(
ankle_R/ankle_L),因此腳部不會滑動。 - 剪裁區域:一個螢幕空間剪裁,用於隱藏身體在某物後面(樹籬、牆壁邊緣)的部分。
- 牆面平面物品:牆上的平面佈景(窗簾、海報);將其排序到其牆壁的最遠端。
- 實用燈光:場景中可見的光源(燈具、發光的窗戶)。
習慣
- 先看再聲稱。渲染幀、讀取頁面,然後說出您看到的內容。
- 一個變更、一次受影響鏡頭的重新渲染、一次重新檢查,附帶頁面。
- 當一個排練持續失敗時,簡化它或選擇一個更清晰的角度。永遠不要用模糊、黑暗、剪接或字幕來隱藏解剖結構。
- 將使用者給您的每個修正寫入集數的
review/LOG.md中,如果是一般性的,則寫入專案根目錄的STAGING_NOTES.md中(在每個集數開始時閱讀它)。永遠不要寫入插件自己的資料夾。