Communitygithub.com

igm61799-cloud/zoom-explainer-3d

用程式碼製作3D「無限縮放」解說影片(MP4),以連續不間斷的攝影機運動跨越好幾個數量級,並在螢幕上即時顯示測量值與熟悉的對比物體。完全透過程式碼繪製(Three.js、無頭Chrome搭配GPU、ffmpeg),不使用任何影片生成模型。

zoom-explainer-3d 是什麼?

此技能專為製作「無限縮放」風格的3D解說影片而設計,能將極端尺度變化可視化——例如從一顆鹽粒縮小到原子等級,或從晶片放大到城市。它採用單一連續鏡頭、即時測量數值、依尺度變化的細節、熟悉的對比物體,以及一個結局亮點,所有內容均由Three.js與無頭Chrome在GPU上渲染,最後用ffmpeg合成為MP4影片。支援Claude Code、Cursor、Codex等AI代理,用戶只需提供主題,AI便會研究真實尺寸、規劃場景、產生程式碼,並引導渲染流程。技能還包含模板專案,以解決精確縮放、景深、確定性渲染等難題,同時提供豐富的參考資料,幫助使用者避免常見錯誤,確保輸出高品質的科學解說動畫。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/igm61799-cloud/zoom-explainer-3d/tree/HEAD

在你喜歡的 AI 中提問

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

說明文件

3D 縮放解說器

這是一種比任何圖表都更能解釋尺度的格式:從每個人都知道的物體開始,不間斷地飛入其中,在螢幕上保留一個數字告訴觀眾他們已經走了多遠,最後以一個他們意想不到的事實作結。此技能的參考結果是「沒有東西是真的鋒利」:一把刮鬍刀片、26次對半、一個鐵原子,以及其邊緣仍然約有300個原子寬的事實。

assets/template/ 是這個已完成的專案。從它而不是從空白檔案開始:困難的部分(在沒有精度損失的情況下縮放八個數量級、隨尺度變化的細節、景深、確定性渲染器)已經在那裡解決,並且經過了好幾輪才搞定。

公式

保留全部五個要素。每個要素都在發揮作用。

  1. 一個連續鏡頭。 重點在於觀眾永遠不會迷失位置。一個剪輯會重置他們對尺度的感知。
  2. 一個即時測量。 一條固定在主題上的細條、一個每幀都變化的數字、一個對半(或加倍)的計數,以及兩三個描述當前視野的詞。這條細條是觀眾唯一需要閱讀的東西,所以它必須誠實:它在場景中的長度確實就是顯示的數字。
  3. 主題在每個尺度都會改變特性。 拋光變成研磨痕跡,再變成碎屑,然後變成晶粒,再變成圓角,最後變成原子。如果表面在三秒鐘內看起來都一樣,那麼縮放就會被解讀為什麼都沒發生。
  4. 對比物體。 當縮放經過每個尺寸時,一個該尺寸的熟悉物體會放在主題旁邊,並標示其名稱和尺寸:鹽粒、頭髮、紅血球、細菌、病毒、電晶體、抗體、DNA。它們把一個抽象的數字變成「比病毒還小」。
  5. 一個亮點。 快速拉回你開始的地方,並展示這次旅程唯一的那個數字。

工作流程

1. 建模前先研究

影片只有在真實的情況下才值得製作。查閱真實尺寸(網路搜尋,盡量使用主要來源),並為主題和每個對比物體寫下:尺寸、來源,以及你正在簡化的任何內容。幾何形狀是根據這些數字建立的,所以畫面不能偏離事實。最後向使用者報告來源和簡化內容;他們會提出疑問。

選擇6到9個對比物體,每個大約比前一個小至少3倍。比這更近的話,它們的標籤會碰撞;比大約30倍更遠的話,螢幕會空好幾秒。

2. 在有用時顯示計劃

如果使用者要求先看計劃,或者簡報留下了真正的選擇空間(旁白或無聲、語言、亮點是什麼),則提供一個簡短的表格:時間、尺度、視野中的內容、對比物體。否則就直接進行;沒有人要求的計劃只會延遲第一次渲染。

3. 設定專案

cp -r <skill>/assets/template <project>/ && cd <project> && npm install
node render.mjs --stills 1,10,20,30,40

第二個指令應該會印出GPU名稱並寫出五張JPEG到 out/。如果它報告 SwiftShader 或 llvmpipe,則渲染是在CPU上進行的,將會耗費數小時:在繼續之前先修好GPU旗標(參見 references/pitfalls.md)。

4. 調整場景

main.js 是一個檔案,分成幾個區塊。在進行任何結構性更改之前,請先閱讀 references/techniques.md;它解釋了每個部分為什麼這樣建構。對於一個新主題來說,通常需要更改的部分是:

main.js 中的區塊要替換的內容
constants以公尺為單位的物理數據、起始尺寸 L0、對半次數 HMAX、時間軸
subject surface橫截面 prof()、輪廓裁剪、表面特徵表格 FEATS(波長、類型、強度)
finest scale原子晶格(或最後階段由什麼組成)
things for scaleaddObj(name, sizeText, sizeInMetres, geometry, material, placement) 列表
overlayLABELS(每個縮放等級視野中的內容)、最終說明文字
camera keysK_AZ、K_EL、K_TY、K_D、K_AP 作為縮放等級的函數

對於形狀不同的主題(晶片、葉子、一張紙),保留機制並替換輪廓和特徵。對於向外縮放,則反向執行相同的時間軸並說「加倍」。

5. 在渲染影片之前檢查靜態圖

渲染分佈在時間軸上的8到10張靜態圖,用 ffmpeg 將它們拼貼成接觸表並進行檢查。然後修正你看到的問題並重複。這個循環是品質的來源;參考影片第一版中的每個問題在靜態圖中都可見,而在程式碼中卻都不可見。特別檢查:

  • 曝光。 第一遍幾乎總是過曝。金屬應該大多是暗的,帶有清晰的亮部。
  • 任何被畫面邊緣切掉的東西,尤其是靠近頂部的對比物體。
  • 標籤位於明亮區域上方或彼此重疊。 將測量標籤保持在空的黑區。
  • 每個階段是否看起來像其標籤所說的那樣。 如果標籤說「晶粒」而畫面是條紋,那麼其中一個是錯的。
  • 第一幀和最後一幀,因為它們是縮圖和重點。
ffmpeg -y -i a.jpg -i b.jpg -i c.jpg -i d.jpg -filter_complex "[0][1]hstack[t];[2][3]hstack[u];[t][u]vstack,scale=1920:-1" sheet.jpg

6. 渲染並驗證結果

node render.mjs --full --o video.mp4            # 如果有旁白則加上 --audio vo.wav

在背景執行它;一個45秒的1080p影片在獨立GPU上需要幾分鐘。然後檢查檔案本身,而不是你之前製作的靜態圖:探查持續時間和大小,提取一個概覽網格,並從繁忙的片段中提取六個連續幀以檢查閃爍。精細的程序化細節壓縮效果很差,所以預期檔案會很大,並在需要時製作一個較小的副本:

ffmpeg -i video.mp4 -vf "fps=1/3,scale=640:-1,tile=4x4" -frames:v 1 overview.jpg
ffmpeg -ss 13 -i video.mp4 -vf "crop=960:540:480:270,tile=3x2" -frames:v 1 consecutive.jpg
ffmpeg -i video.mp4 -vf scale=1280:720 -c:v libx264 -preset slow -crf 25 -maxrate 4200k -bufsize 8400k small.mp4

清楚說明你驗證了什麼以及沒有驗證什麼。幀網格證明畫面是正確的;它們不能證明運動感覺是對的,所以應該說使用者應該觀看它。

預設值

  • 無聲。 除非要求,否則沒有音樂、沒有音效、沒有旁白。這個格式本身就足夠了,而且它的參考來源也沒有旁白。
  • 文字僅包含數據和名稱。 測量值、對半計數、視野中的內容、對比物體的名稱和尺寸、一個最終數字。如果添加了旁白,就刪除語音已經說過的每個標籤,因為閱讀和聆聽相同的詞語會分散注意力。
  • 1920x1080,30 fps,40到50秒,以1.5倍渲染後再降頻。對於垂直影片,更改 W 和 H 並重新檢查每個靜態圖;構圖不會自動轉移。
  • 標籤使用使用者觀眾的語言,這不一定是他們聊天時使用的語言。如果不清楚,請詢問。

添加旁白

僅在被要求時才添加。將劇本寫成簡短的台詞,每句屬於一個階段,產生或接收音訊,取得單詞時間戳(faster-whisper 效果很好),然後根據音訊驅動縮放:縮放等級成為一個關鍵幀化的時間函數,在解釋一個階段時保持不變,並在台詞之間移動。將音訊傳遞給 render.mjs --audio。在每個停頓期間讓一些小事情發生(光線掃過、物體到達、原子振動),否則暫停的縮放看起來就像凍結了一樣。

參考檔案

  • references/techniques.md - 模板如何運作及其原因:圍繞焦點縮放、尺度視窗化的程序化細節、球體假象、景深、錨定在物理空間中的物體、確定性渲染器。在結構性更改之前閱讀。
  • references/pitfalls.md - 已經遇到過的失敗及其修復方法。當渲染看起來不對或工具行為異常時閱讀。
  • MASTER_PROMPT.md - 用於開始新影片的填空提示,以及符合這個公式的主題點子。

相關技能