卡通短片:點子 → 腳本 → 旁白 → 完成 MP4
視覺風格:平面2D豆頭卡通角色(以畫布繪製的「卡片」,帶有梅子色輪廓),位於色彩豐富的3D世界中,帶有黑色墨水輪廓、繪畫紋理、景深與滑行攝影機。輸出為1080x1920、30 fps,長度與旁白完全一致。使用者的聲音保持不變。背景音樂與音效為合成音,音量設定為旁白音量的 50%。已在《從未離開的士兵》(19.7秒,8個鏡頭)中獲得驗證。
規則
- 故事、角色與鏡頭必須始終保持原創。切勿逐鏡頭複製其他創作者的作品。可針對相同點子提供原創詮釋。
- 不得使用真實、具名且在世的個人作為角色,亦不得使用品牌吉祥物或標誌。
- 除非使用者要求,否則不加字幕。相符性文字(如雕刻訊息、招牌)可以接受,且必須正確閱讀(不可鏡像翻轉)。
- 切勿編輯或重新調整旁白時間。畫面需根據旁白時間進行調整,每個視覺反應應在其對應字詞前0-3幀內發生。
- 音訊電平: 背景音樂設定為旁白電平的50%(−6 dB,門控RMS)。音效亦為50%或略低,峰值經限制,確保無突發聲響超越旁白。務必使用
mix.py進行混音,不得手動操作。不得使用會改變此比例的壓縮或閃避效果;僅在整體混音上應用一次線性增益與峰值限制器。 - 隨時透過任務清單告知使用者進度。在進行長時間渲染前,先發送一張靜態聯絡表。
階段 1:輸入(始終為第一步)
如果音檔已附加,則跳至階段4。如果腳本也已提供,則使用其進行時間對齊。 否則,提出一個 AskUserQuestion(或若該工具缺失,則使用純文字):「你從哪裡開始?」
- 旁白已準備好:要求上傳旁白,以及腳本文字(若有,腳本可使時間對齊更精確)。收到後前往階段4。
- 我有腳本,需要旁白:若有必要,根據階段3緊縮腳本,連同錄音技巧一併回傳,要求上傳,然後前往階段4。
- 需要影片點子與腳本:前往階段2。 同時詢問目標長度(若使用者未提及)。預設為20-30秒;45-60秒亦可接受。
階段 2:10個影片點子
在一次回覆中提供恰好10個點子,編號,並要求使用者回覆數字(或「更多」)。每個點子需包含:
- 標題(5-8個字,激發好奇心,例如「從未離開的士兵」)。
- 鉤子句:第一句旁白,以事實形式陳述的矛盾(「一個人賣掉了艾菲爾鐵塔。兩次。」)。
- 轉折:一句話說明(影片結尾的諷刺報應)。
- 為何適合動畫:2-3個重要的視覺時刻(崩塌、揭露、追逐)。
- 真實或傳說:清楚說明其為有記載的歷史、有爭議的記載或民間傳說。
什麼點子「完美」符合此格式:
- 一個具有可展示的物理因果關係的驚人故事。
- 一個清晰的普通人角色、逐步升級的風險,以及最後一句話的轉折。
- 一個能由簡單3D形狀加上卡通卡片(城鎮、橋樑、船隻、城堡、沙漠、實驗室、宮殿)構建的場景。
- 將10個點子混合涵蓋不同時代與主題:古代、中世紀、1800年代、現代、科學、動物、發明、災難、奇怪法律、幸運意外。
- 對於任何以真實事件呈現的內容,在提供前務必透過網路搜尋驗證關鍵事實。切勿將病毒式傳說當作事實呈現。若使用者無論如何都想要,可將其框架為「傳說稱」。
- 不得以真實在世人士為笑柄,不得包含色情或政治內容。
階段 3:腳本(使用者選擇點子後)
僅撰寫旁白(口語文字中不含舞台指示),字數約為每秒3.7個字:20秒 ≈ 75字,30秒 ≈ 110字,60秒 ≈ 220字。公式如下:
- 鉤子(第一句,無鋪陳):荒謬的事實。
- 場景(1-2行):時間、地點、人物,一個具體細節。
- 升級(2-4個節拍,每個更大)。其他人懷疑或嘲笑。使用一個誇張笑話。
- 謎團或轉折:「但當…」/「你知道,」引出真正的機制,通常使用一個日常比喻。
- 轉折/報應:簡短、諷刺,且為影片的最後一句話。 使用簡單的英語口語、縮寫,句子長度約8-15個字,數字以文字書寫。切勿描述觀眾已看到的內容。
然後回覆:
- 可複製的腳本區塊,附帶字數與預估長度。
- 一段視覺計畫(你將動畫化的鏡頭)。
- 錄音技巧:一個穩定、溫暖的敘事者聲音;ElevenLabs效果不錯(深沉的敘事者聲音,速度約1.05-1.1,穩定度約45-55%)。Mp3或wav格式皆可。在句子結尾留下自然的停頓。輸出時不含音樂。
- 要求:「旁白準備好後請上傳,我將製作完整影片。」 保留最終腳本文字。其驅動階段4的時間對齊,因此無需語音辨識。若使用者錄製了修改版本,請要求提供最終文字。
階段 4:建構影片(旁帶上傳後)
從此處開始,不間斷地完成所有步驟。僅在時間無法對齊時提問。
4.0 取得工具包
程式碼工具包位於此技能資料夾內部的 kit/(引擎、工具、範例,以及來自 github.com/mromidev/claude-animated-shorts 的 vendored three.js r160 和 toon.ts Pen 函式庫,兩者均為 MIT 授權)。使用 find / -name SKILL.md -path "*cartoon-audio-short*" 2>/dev/null 找到資料夾,並將其 kit/ 視為唯讀。
然後執行 bash <skill>/kit/tools/setup.sh ~/shorts/<slug>。它會將引擎和工具複製到專案中,安裝 vendored three.js,使用 Node 22 module.stripTypeScriptTypes 從 toon.ts 中剝離型別,並連結 Playwright。無需網路。若 vendored 檔案缺失,則回退至 npm 或 git clone。
- 需求:Node 22.6+、帶有 numpy + Pillow 的 Python 3、ffmpeg,以及帶有 Chromium 的 Playwright(若缺失則執行
npm i -g playwright && npx playwright install chromium)。 - 若套件註冊表被封鎖,通常可使用 GitHub 上的 git。切勿停用 TLS 或繞過代理。
- Chromium:使用預先安裝的 Playwright 瀏覽器,搭配
--use-angle=swiftshader --enable-unsafe-swiftshader --ignore-gpu-blocklist。這可提供 CPU WebGL,每幀約需3-10秒。
4.1 時間對齊
執行 python3 timing.py voice.mp3 script.txt --out work。
- 若已安裝 whisper 或 faster-whisper,則使用單字時間戳記。
- 否則,將腳本短語(按標點符號分割)與靜音偵測到的語音段落進行對齊,使用 DP 演算法匹配音節與持續時間,並懲罰段落內部的句子結尾與短語內部的長間隔。
- 若無 ASR 且無腳本,則要求提供腳本。Claude 無法聽見音訊。
- 檢查
work/phrases.json:停頓應落在句子結尾。總幀數 = round(持續時間 × 30)。
4.2 鏡頭計畫(程式碼前的 work/PLAN.md)
為每個鏡頭製作一行:幀數、文字、場景、光線、攝影機移動、角色/姿勢/表情、效果與音效提示。
- 幀0已是鉤子圖像。
- 通常一個鏡頭對應一個短語。將極短短語合併至下一個鏡頭。
- 逐句說明每個句子。道具承載笑點。
- 變化鏡頭大小:鉤子中景 → 寬景揭露 → 雙人鏡頭 → 關鍵物體的特寫插入 → 反應特寫 → 為報應所做的環境移動。
- 使用光線表現節拍:白天用於普通,金色用於衰退或戲劇,夜晚藍色用於解釋。時間跳躍使用6幀白色閃爍。
- 轉折句使用瞬間停頓(音樂停止、低音撞擊、推近與旋轉)。最後鏡頭的物理報應落在最後一個字上。
4.3 世界 (web/main.js)
保留引擎部分:卡通材質、墨水收縮、add/tbox、天空、燈光、卡片、渲染目標/後製、applyLight、drawActors、swapForNd、renderFrame。替換 // ---------- world ---------- 與 // ---------- cards ---------- 之間的範例世界,以及 worldState() 中的故事部分。
- 使用帶有畫繪製畫布紋理(
paint.js:木板、橫樑、腐木、石頭、苔蘚/常春藤、草、泥土、灰泥、屋瓦、大理石、橫幅、雕刻文字)的基本形體進行建構。以相同的平面且帶有深色縫隙風格撰寫新的繪製器。 - 使用
tbox保證紋理密度一致,2步卡通漸層,以及霧 = 地平線顏色。 - 背景:小山(半埋球體)、山脈(圓錐體 + 雪帽)、柏樹/松樹、遠方房屋、繪製的雲朵廣告牌。
- 場景部件(崩塌、墜落、門)是由
worldAt(f)驅動的0..1進度樞紐群組,具有緩和與交錯的部分。 - 曲線相符性文字使用平面 UV。檢查其是否鏡像。
4.4 角色 (web/roman.js → web/toon.js)
romanFront(p, outfitKey, opts)在 600x1000 的設計畫布上繪製,腳底在 y=975。卡片高度為 2.25 公尺,因此 1 單位 = 0.00225 公尺。- 將服裝新增至
OUTFITS(束腰外衣/披風/盔甲/頭盔/頭髮/帽子/鬍鬚/圍裙/洋裝/長袍),並以相同風格新增新頭飾與道具。 - 手臂姿勢:垂手、持矛、指人、舉起、揮手、叉腰、捧腹、按太陽穴(+旋轉)、舉升、伸手(+舉升)、托腮、持盾、交叉、豎拇指。
- 表情:toon.ts 的 FACE 集合,加上打鼾、固執、瞇眼。可擴展 FACE 以容納更多。
- 編輯後使用
cat web/toonbase.js web/roman.js > web/toon.js重建。在使用新設計前,先渲染角色測試表。 - 廣告牌僅轉向偏航,具有接觸模糊與 Alpha 測試陰影,且永遠不會被世界通道描邊。
- 使用
q()四捨五入的值來建構卡片鍵(以便畫布僅在可見變化時重新繪製)。 - 分離部件(例如抬起頭盔)是其自身的卡片,與
headCenter(seed)對齊:y = DECK + (partY − hc) × 0.00225。
4.5 運動:流暢且有生氣 (web/motion.js)
- 攝影機:
camFromKeys(keys, f, {kicks})。使用更平滑的滑行(18-45幀),用於揭露與甩鏡的easeOut,以及用於曲線移動的path通過點(Catmull-Rom)。每個靜止鏡頭都有微動,且沒有任何東西靜止超過4幀。在戲劇性場景使用3-5°的旋轉,在撞擊時使用7幀的翻轉抖動。 - 連續性:偏好連續移動(從特寫拉回寬景、跟焦、透過甲板的起重機、推近至物體)。僅在位置或時間跳躍時使用硬切,並伴隨閃爍。
- 角色永不凍結:對每個卡片應用
idle(f, seed)、blinkAt眨眼,以及在重音字詞上點動頭部。 - 動作:預期動作 →
back超調 →spring穩定。跺腳是2幀下沉 + 灰塵噴發 + 踢腿。笑聲是交替傾斜 + 點動。 - 次要運動:橫幅布料飄動、葉子/灰塵/水滴/Zzz效果卡片、流水。總有東西在移動。
- 行走:
walk()提供距離 + 腳步相位。腳著地,點動3-7%。 - 鏡頭:特寫與中景使用景深(cInf 8-14px),對焦於眼睛。寬景保持清晰。跟焦約需14幀。
4.6 視覺檢查(完整渲染前)
在每個鏡頭的中間點、轉場與關鍵動作處渲染靜態圖:node render.mjs stills/a "5,40,..." 然後 python3 sheet.py stills/a stills/sheet_a.jpg。檢查聯絡表並修正這些陷阱:
- 狹窄垂直構圖:水平半寬度 = d·tan(hfov/2),其中 hfov = 2·atan(tan(vfov/2)·0.5625)。在 4 公尺且視角 40° 時為 ±0.8 公尺,因此將角色在深度上分層佈置。
- 跨越臉部的欄杆或柱子(攝影機在欄杆內或約 2.5 公尺高)。穿越房屋、屋頂或灌木叢的攝影機路徑。距離約 2 公尺以下的近景道具。主角被柱子遮擋。
- 鏡像文字。偏移方向錯誤的分離部件卡片。
- 擠出材質群組:0 = 端蓋,1 = 側面+頂部。
- 缺少墨水:調試僅邊緣輸出。墨水半徑在 1080 下約為 2.5 px。天空計為遠距離深度,而非卡片。
- 將聯絡表連同一行鏡頭摘要發送給使用者,然後開始完整渲染。
4.7 音效 (audio.py → 音軌 → mix.py)
為故事重寫提示表;合成器保持不變。audio.py 僅寫入音軌(music.wav、sfx.wav)。
- 音樂:一個簡短的進行曲式循環(大鼓/小鼓、撥奏貝斯、銅管墊)。在轉折句處停止,然後一個低沉的低鳴持續。
- 事件音效(以幀/30為單位):大型移動時的颼颼聲、跺腳時的砰聲、崩塌時的隆隆+破碎聲、金屬刮擦聲、揭露時的叮噹聲、轉折時的瞬間停頓、吱吱聲、折斷聲、水花聲、打鼾聲、樹葉聲、水環境音。
- 使用
python3 mix.py voice.mp3 music.wav sfx.wav進行混音。它將音樂設定為旁白門控 RMS 的恰好 50%(−6 dB),音效設定為 50%,且峰值限制在旁白峰值的 0.7 倍。它會列印測量電平:確認音樂相較旁白顯示 −6.0 dB,且音效等於或低於此數值。 - 在製作音效前鎖定畫面時間。任何時間變更都意味著重新執行 audio.py 和 mix.py。
4.8 渲染 + 完成
- 使用 Bash
run_in_background執行node render.mjs frames "0-<N-1>",由 Monitor 循環監控,報告進度並捕獲錯誤或程序退出。設定RESUME=1可在中斷後繼續。請勿在小機器上同時執行重量級的 Python 任務。 - 執行
bash finish.sh "標題"。它應用一次線性增益至約 −14 LUFS,加上 −1 dBFS 峰值限制器,編碼 H.264 CRF 17 + AAC,執行凍結/黑幀與響度 QA,並寫入out/qa_sheet.jpg。檢查 QA 表。凍結範圍 ≥0.4 秒或黑幀需要修復。 - 使用 SendUserFile 傳送 MP4,並附上幾行關於每個鏡頭顯示內容的描述。提供字幕、調整或清單中的下一個點子。
引擎注意事項(保存在工具包中;若重建則保留)
#include <fog_vertex>/<fog_fragment>必須各自獨立一行。- 最終通道寫入
linearToOutputTexel(...)(渲染目標為線性 HalfFloat)。 - 法線+深度通道為每個網格交換材質:世界 → 法線/深度,卡片 → Alpha 測試遮罩(rgb 0,a = 深度),模糊/雲/天空隱藏,水 → 平坦法線。在該期間關閉霧與陰影。
- 墨水僅應用於深度跳躍的近側。皺褶來自法線點積。跳過相鄰卡片。墨水在約 140-520 公尺處淡出。
- 景深:48 次採樣,帶有逐樣本 CoC 測試(無前景溢出)。
- 太陽來自每個燈光預設的方位/仰角。陰影攝影機以每個鏡頭動作的中心為準。
架構(編輯工具包的參考)
web/index.html透過本地 HTTP 伺服器載入main.js(ES 模組)。main.js:渲染器、卡通材質、世界、卡片(1200x2000 CanvasTexture 平面,原點在腳底)、通道(色彩 RT 採樣 4)→ 法線/深度 → 墨水+色調(飽和度、增益/提昇、)