3D 相機字幕
取代 After Effects 的 3D 相機、景深、路徑文字、時間抽幀至 15 fps 與動態模糊效果,為 HyperFrames 重建為一個確定性的逐幀繪製引擎。一個時鐘同時繪製背景、遮罩與每個字形。沒有任何東西是 CSS 動畫。
使用時機 / 不使用時機
- 使用於:靜態相機的說話者鏡頭(虛擬人物或真人)、橫向構圖、中景或更遠的景別,每個片段 5–20 秒。文字必須在說話者周圍的深度中表現。
- 不使用於:一般字幕、移動或手持攝影機(遮罩與背景變換預設鎖定鏡頭)、極特寫(頭部後方空間不足),或是人物遮罩模型無法分離的主體。
需求與副作用(完整列表)
- 工具:
- Node 22+ 與固定版本的 HyperFrames CLI,
npx [email protected](從registry.npmjs.org下載)。每個下方指令請使用此確切版本。 ffmpeg需在 PATH 中。- Python 3 搭配
fonttools、brotli、numpy、pillow。
- Node 22+ 與固定版本的 HyperFrames CLI,
- 遮罩:
npx [email protected] remove-background在本地執行。首次執行會下載人物分割模型(約 170 MB)到~/.cache/hyperframes/。 - 渲染時間: 合成場景會在預覽/渲染時從
cdn.jsdelivr.net載入 GSAP 3.14.2。 - 文字時鐘: 使用者自行在本地執行的任何詞彙級轉錄工具。起始時間準確度很重要;純 Whisper 的起始時間會延遲。
- 字型: 使用者提供的檔案。請確認授權允許嵌入。
- 手繪風格(可選): 需要安裝並設定
p5-paint-animation技能(其設定會下載固定的 puppeteer、Chrome for Testing、p5 與 p5.brush)。build-sprites.py會以無頭模式執行它;影格會被寫入該技能的out/目錄,之後再移除。 - 無其他需求: 無憑證、無付費呼叫、無上傳。檔案僅寫入專案目錄(
assets/、renders/)。
前置作業(每個片段一次)
- 片段與背景。
bash scripts/prep-take.sh <take.mp4> <start_s> <dur_s> <project>/assets會產生:portion.mp4:音訊來源。plate-tall.mp4:在兩側各反射填補 240 像素、上方 480 像素、下方 240 像素,確保快速切入、平移與拉遠不會露出邊緣。person.webm:Alpha 遮罩,相同的影格數。- 此腳本接著會檢查背景與遮罩是否與片段相符(尺寸、影格率、影格數),並在不符時失敗。
- 文字時鐘。 片段的文字時間點(以片段開始後的秒數為單位)。
- 字型。 挑選 2–3 個角色(字幕 / 主體 / 環狀),接著執行
python3 scripts/font-metrics.py assets/metrics.js key=font.woff2[@wght=…,opsz=…] …。- 可變字型必須在此處傳遞其軸向參數,並且在 CSS 中固定(
font-variation-settings、font-optical-sizing: none)。否則瀏覽器的 opsz 會跟隨尺寸,導致文字重疊。
- 可變字型必須在此處傳遞其軸向參數,並且在 CSS 中固定(
- 輪廓。 在放置任何東西之前,從
person.webm的 Alpha 通道讀取頭部框線與肩膀線條。
建置
- 將
assets/kit/{cam3d.js,tables.js,finish.js}與metrics.js複製到專案的assets/目錄。 references/worked-film.html是完整的參考影片。它包含兩個鏡頭、一個身體遮罩過場、兩種環狀類型、一個飛越鏡頭、一個結尾與調色;其媒體檔案不包含在內。references/recipes.md包含深度優先群組、環繞環、階梯式以及手繪文字。C3.init(metrics, {W, H}):- 鏡頭保持教學中的垂直視角(F = 1326.1·H/1080),因此
tables.js可在任何寬度下不經縮放套用。 - 在寬度超過 1440 的影格上,將
(W − 1440) / 2加到wipe.x。
- 鏡頭保持教學中的垂直視角(F = 1326.1·H/1080),因此
鏡頭語法
挑選 4–6 個節拍。將每個口語子句分割成各自的群組。
| 節拍 | 建置 | 規則 |
|---|---|---|
| 快速切入 / 推進 | camA 表(19 f,從 502 px 低位)然後一個 linear 緩慢移動 | 背景 S0 1.1–1.3;影格永遠不會靜止 |
| 深度群組 | 每個子句 2–3 個字幕群組,位於 D 1250 / 1500 / 2200 | 近處較大且陰影較大;緩慢移動與平移揭示視差 |
| 主體在後 | 主體文字位於背景層的景深度,像報紙標題般橫跨頭部 | 頭部遮住中間字母;至少 60% 保持可讀;上升筆畫在影格內 |
| 視差平移 | swing 區段,tx 420 | 舊佈局在 3 步內淡出;下一個佈局透過視差進入 |
| 身體遮罩過場 | 說話者自己的遮罩,brightness(0) blur(),前沿來自 wipe.x | 鏡頭 A 裁剪帶狀左側,鏡頭 B 裁剪右側;兩側都做拉遠 |
| 環繞環 | 水平圓圈在說話者前方(中心 Z 2000),從上方 11–16°,旋轉 | 文字從側面以小字進入(隨著說話),在前方旋轉,然後安定;下方弧線翻轉以正向閱讀 |
| 飛越鏡頭 | 片語位於 D 1500 / 2000 / 2500,相機在其間擺動 | 焦點跟隨片語 |
| 階梯式結尾 | 推進區段;字幕文字沿對角線越深越小 | 推進將近處文字推開 |
規則
- 運動:
- 文字抽幀至 15 fps(其自身的動畫以及它所看到的相機)。背景與遮罩每個影格移動。
- 動態模糊為 7 個幽靈,跨越半個 15-fps 步長。旋轉環使用
shutter: 0.5。 - 字幕領先聲音 0.2 秒,並對齊 15-fps 格點:
fr(t) = 2·round((t − 0.2)·15)。 - 入場依靠
ENTRY上升:字幕 30 px,主體 110–260 px。環狀文字沿路徑最後 30–44 px 緩動。僅在相鄰位置尚未就座時使用RING_ENTRY的超調。
- 深度:
- 每個群組都有自己的 D。背景 3000,字幕 1250–2400,環繞環約 1100–2700。
- 深度陰影
[6, 16, 0.5, 1500]按 1500/(D − cz) 縮放。 - DOF σ = 6.7·|D − focus|/D px(以 1080 高為準)。平面字幕上限為 1.2 px;環狀字形承受完整模糊。
- 尺寸:
size/rise是在落地相機 (tland) 上的螢幕像素。精靈以其螢幕尺寸渲染。 - 間距:
- 環狀文字始終通過
ringLine(螢幕前進量;類型:字距 1.10,間距 26–30;手繪:字距 1.0,間距 28)。 - 正在旋轉的環每個姿勢重新佈局。
- 環狀文字始終通過
- 遮擋:
- 環狀繪製在說話者前方。
- 僅在文字「有意」穿過頭部後方時,才將單字分割為後/前實例(
side、zSplit)。
- 可讀性:
- 字幕放置在畫面的暗側。
- 跨越皮膚或淺色衣物的文字需加暗色光暈。
- 螢幕上不留結尾句點。
- 調色(可選):
finish.js提供曲線、膚色飽和度 1.12,以及每個影格重新產生的顆粒感。將不透明場景(背景 + 後方文字 + 遮罩)放在一個帶濾鏡的包裹器中。給予前方文字相同的調色,並在上方合成顆粒,因此被分割為後/前的單字保持同一顏色(參見references/worked-film.html)。
風格
- 編輯風格: 壓縮的展示襯線體,主體用斜體;字幕用文字襯線體;奶油色加上一個強調色。
- 粗體: 主體用重型無襯線體,淺色字幕,一個飽和的強調色(參考影片)。
- 手繪: 來自
scripts/hand/build-sprites.py的 p5.brush 書寫精靈:- 每個單字從其開始時自行書寫入場。
- 環狀文字以完整單字放置,旋轉至切線方向並按深度縮放,位於更大、更扁平的環上。
- 配方在
references/recipes.md中。
驗證
npx [email protected] check . --no-contrast。幽靈圖層會觸發 WCAG 對比度檢查;快速切入與遮罩過場的接縫是設計上的重疊。- 在預覽頁面中,貼上
scripts/frame-bounds.js並執行__frameBounds(0, dur)。- 必須回傳
[]:沒有群組在可視情況下超出影格 5 步以上。
- 必須回傳
- 貼上
scripts/glyph-gaps.js並在靜止時執行__glyphGaps(t)。- 沒有跨單字的接觸。
- 平面字測量為一個方框(下降筆畫會導致誤報)。斜體 f 的突出部分讀數為負。遮罩過場帶兩側的文字都會顯示。
- 單字間距:渲染後的單字間距約等於一個空格前進量。
- 對每個節拍進行快照,使用
npx [email protected] render . --crf 12渲染,並檢查每個節拍的全解析度影格。
限制
- 遮罩邊緣在細髮上會閃爍。鏡面填補在快速切入期間會短暫顯露。
- 填滿畫面的說話者留給背後的空間很少:可將主體抬高至報紙標題高度,或藏在肩膀後方。
snapshot --at共用同一個頁面,因此顆粒不會在每次擷取之間重新產生。請在渲染檔中評估顆粒。- 啟用調色與多個幽靈圖層的渲染成本約為普通渲染的 2 倍。