Communitygithub.com

三維動畫

用 Remotion 和 three.js 把短片寫成程式,並交代攝影機、光、運動與聲音。

三維動畫 是什麼?

它把三維片段當成一條被導演的鏡頭,而不是灰底裡轉圈的物件。會先定攝影機、光、運動與聲音,再用 Remotion 和 three.js 逐幀寫出來。適合產品或物件動畫、有電影感的三維短片、直式短片,或一條看起來發平的現成場景。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Haseeburrahmann/3d-animator-skill/tree/HEAD

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

3D 動畫師

一個簡單的提示只會讓你在灰色虛空中得到一個旋轉的物體:靜態的鏡頭、平淡的燈光、線性的動作,而且沒有音效。一位動畫師在編寫任何程式碼之前會先思考四件事:鏡頭、燈光、動作和音效。這項技能讓你像那樣思考,然後以程式碼編寫每一幀。

這些規則來自 WhatsNext AI (@whats.nextai) 的製作流程,並根據表現最佳的 Reels 進行調整:

  • 靜態幀低於 10%;
  • 每 10 秒約 0.7 次硬剪輯;
  • 音樂約比人聲低 9 分貝。

0. 在編寫任何程式碼之前:先進行導演

首先編寫一個分鏡表。每個節拍佔用一行:

節拍 | 秒數 | 主體 | 鏡頭移動 | 燈光變化 | 動作事件 | 音效提示

分鏡表的規則:

  • 第一幀就要顯示主體。 不要從黑色淡入,不要顯示標誌,不要從空舞台開始。
  • 大約每 1.5 秒就改變一個可見的元素: 鏡頭移動、揭露或燈光變化。
  • 每個節拍只改變一件事: 規模(廣角 ↔ 微距)、角度、燈光或物體的狀態。絕不一次改變所有。
  • 重新安排同一個物體,而不是切換到不相關的場景。 結尾的鏡頭應該與開頭的鏡頭相呼應。
  • 沒有主體?選擇一個有內部的物體,讓鏡頭有地方可以去:手錶、手機、引擎、街區、電纜。規劃一個插入鏡頭或揭露鏡頭。

1. 鏡頭 (references/camera.md)

  • 鏡頭絕不靜止。 在每個鏡頭之上添加由兩個不可通約的正弦波組成的緩慢環繞和浮動,確保沒有靜態幀。起始值:約 0.17 弧度 × sin(0.8t) + 0.09 弧度 × sin(1.9t + 0.7)。
  • 在關鍵鏡頭之間使用緩入緩出(三次方)進行移動。 絕不使用線性移動,也絕不瞬移。
  • 推軌,不要縮放。 移動鏡頭位置,並將物體的視野保持在 30° 到 40° 之間。廣角視野會扭曲產品。
  • 揭露時推近。提供上下文時拉遠。 每個節拍一個移動。
  • 少用硬剪輯: 每 10 秒約 0.7 次。動感來自鏡頭,而非剪輯。
  • 直式 9:16 構圖:
    • 將主體保持在畫面高度的中間 60%。
    • 上方 15% 留給標題。
    • 下方 25% 留給字幕和應用程式 UI。
    • 在 Instagram 和 TikTok 上,右側保留 150 像素的空白。
  • 景深: 在前景放置某物,主體在中間,背景柔化。在注視點附近添加漂浮的灰塵顆粒或粒子,讓即使緩慢的移動也看起來像是有動感。

2. 燈光 (references/light.md)

  • 深色背景,一種強調色,一個主體。 例如,深藍色 #0B0F18 的場景搭配橙色 #FF914D 的強調色來表示「資訊」。
  • 燈光設置:
    • 半球體填充光:天空 #A9BDE0,地面 #0B0F18,強度約 0.8。
    • 一道來自左上方涼色調的主方向光:強度約 1.5,投射陰影。
    • 一側的暖色點光和另一側的冷色點光,使邊緣能與背景分離。
  • 反射: 使用環境貼圖(經由 PMREMGenerator 的 RoomEnvironment),強度在 0.2–0.6 之間。沒有它,金屬和玻璃看起來像塑膠。
  • 僅在必要時使用泛光:
    • 使用 UnrealBloomPass,閾值 0.9 或更高,強度約 0.4,半徑約 0.4。
    • 應該發光的東西使用 emissive,沒有其他東西會發光。
    • 過曝陷阱: 純白色材質加上泛光會沖淡畫面。對「白色」塑膠使用淺灰色 (#C9CFD9)。
  • 使用霧 (<fog args={[bg, near, far]}/>) 使距離消失在背景色中。
  • 燈光變化就是故事節拍: 當一個零件被命名時它亮起,房間為了一個揭露而變暗,一個閃光落在關鍵時刻。

3. 動作 (references/motion.md)

  • 每個動畫都是關於影格的純函數: t = frame / fps。
    • 絕不使用 Date.now() 或 Math.random()。使用 remotion 的 random(seed)。
    • 絕不使用 useFrame 來製作動畫。
  • 彈出使用彈簧(阻尼 12–14,剛度約 170)。移動使用三次方緩入緩出。僅對傳送帶和粒子漂移等恆定事物使用線性。
  • 相關元素錯開 3–5 影格。 絕不在同一影格移動十個東西。
  • 添加次要動作: 主體物件上的緩慢轉盤旋轉(±0.4 弧度)、漂移的微粒、呼吸式的縮放(±1%)。
  • 停頓是一種選擇。 當它是刻意的戲劇性節拍時,暫停最多 2 秒是沒問題的。否則,總是有東西在移動。
  • 標籤: 簡短的大寫狀態標籤會在它們命名的節拍那一刻彈入。標記重製作品為「3D 重製」。

4. 音效 (references/sound.md)

  • 每個事件一個音效:
    • 大鏡頭移動時的颼颼聲;
    • 揭露時的撞擊聲;
    • 進入揭露前的漸強音(約 2 秒);
    • 標籤上的點擊聲或爆音。
    • 合成它們 (scripts/sfx_synth.py) 或使用 CC0 素材包。
  • 音樂背景比人聲低 6–11 分貝,目標約 9 分貝。 在其下方的旁白進行側鏈壓縮。
  • 寂靜是一種效果。 在關鍵台詞之前讓音樂消失一個節拍,然後在撞擊聲中猛烈回歸。
  • 母帶處理 至 −14 LUFS 綜合響度,真實峰值在 −1.5 dBTP 或以下。將語音金鑰填充至完整長度,以免音樂結尾被切斷。

5. 程式碼規則 (Remotion + three.js)

  • 畫布: 使用來自 @remotion/three 的 <ThreeCanvas width={width} height={height}> 包裹 3D,並且務必包含燈光。
  • 序列: 畫布內部的任何 <Sequence> 都需要設定 layout="none"。
  • 後處理: EffectComposer 可以使用優先級為 1 的 useFrame(() => composer.render(), 1) 接管渲染。這是唯一允許的使用方式,因為 Remotion 每影格推進一次場景,使輸出保持確定性。請參閱 templates/Fx3D.tsx。
  • 狀態: 從單一狀態函數 worldAt(t) 驅動場景,該函數返回鏡頭、舞台和旗標。保持元件無狀態。
  • 渲染: 在 macOS 上當 WebGL 輸出為黑色或不穩定時,使用 --gl=angle 進行渲染。使用 H.264、yuv420p、1080×1920、30 fps。

現成可用的片段(直接複製,不要匯入):

  • templates/Fx3D.tsx:環境反射和泛光。
  • templates/camera.ts:easeCam、orbit、ramp、pop。
  • templates/Motes.tsx:確定性灰塵粒子。

6. 像編輯一樣驗證

  1. 渲染 4–6 張靜止畫面:鉤子、每個揭露以及最後一影格。檢查過曝、主體被字幕或標題裁切、空白影格以及無法閱讀的文字。
  2. 渲染影片,然後執行 scripts/check_motion.sh out.mp4。目標:靜態幀低於 10%,動作 (YDIF) 約為 2 或更高,並且每 10 秒約 0.7 次硬剪輯。如果太靜態,增加環繞或浮動、添加微粒或添加推近。不要增加剪輯點。
  3. 如果有音頻,檢查響度(−14 LUFS)以及音樂是否比人聲低約 9 分貝。
  4. 僅重新渲染失敗的部分。

完成意味著: 分鏡表已存在,每個節拍都有鏡頭移動、燈光角色、動作事件和音效提示,檢查都通過,而且你已經看過靜止畫面。

相關技能