Blender 產品影片
一種方法與實際範例,用於製作一段 45 至 75 秒、可在關閉聲音下觀看的產品影片。 寫實場景(草地、木門、真實天空)承載一個視覺隱喻。簡短的文字疊加 說出畫面無法傳達的資訊。影片結尾轉變為一個由彩色方塊組成的平面網格,這些方塊翻轉 拼出標題與行動呼籲。
一切皆為程式碼:場景、動畫、合成。無需開啟圖形介面。
資料夾內容
| 路徑 | 說明 |
|---|---|
film.json | 調色盤、疊加文字與時間、結尾台詞。請優先編輯此檔案。 |
scripts/blender/build.py | 場景:帶毛髮粒子草地的小丘、門、磨砂方塊、天空、霧氣、渲染設定。 |
scripts/blender/mascot.py | 範例角色:一隻尺寸小到能站在籬笆柱上的體素貓頭鷹。 |
scripts/blender/film.py | 鏡位、攝影機、逐幀動畫。渲染 plates 與 layers。 |
scripts/post/comp.py | 合成器:plates + layers、2D 攝影機運鏡、文字、調色、2D 方塊結尾、ffmpeg 編碼。 |
assets/ | 兩張天空素材(金色、陰天)。請更換為自己的素材。 |
examples/ | 以此流程製作的影片幀。 |
範例影片名為「The Gate(大門)」:相同的方塊以穩定速度滾過敞開的大門,接著 以各種尺寸到達,然後蜂擁而至。大門關閉,之後方塊逐一通過、計數或 被擋下。請將其視為結構參考,然後替換為符合產品的隱喻。
工作流程
請依序執行以下步驟。在每個編號步驟獲得確認後,再繼續花費渲染時間。
- 簡報。 各用一句話說明:目標對象、問題、轉折、承諾、行動呼籲。 決定影片長度(45 至 75 秒)、長寬比以及播放場域。假設為靜音播放。
- 隱喻。 為問題選擇一個實體畫面,為產品選擇一個對該畫面的改變。 一個地點、一個主要道具、一種移動物體。如果需要解釋,請重新選擇。
- 節拍表。 6 到 8 個鏡位。每個鏡位需包含:持續時間、移動物體、疊加台詞(少於 8 個字, 一個概念)、攝影機位置與鏡頭。問題階段使用陰冷光線,產品階段使用溫暖光線。 以表格呈現並取得核准。
- 角色(可選)。 一個小主角能讓視線有休息之處。在建模前先提供 3 或 4 個 平面草圖選項。對照場景調整大小:它必須能放在主要道具上。 使用簡單幾何形狀建構(貓頭鷹由 1 公分的立方體組成)。
- 場景程式碼。 改寫
build.py。單位使用公尺,主要道具位於原點。 以低樣本數為每個鏡位渲染一張靜態幀,在進行動畫前逐一檢視。 - 動畫。 在
film.py中,每個鏡位都有setup_X(建立一次物件)與update_X(t)(為影片時間t放置所有物件)。純時間函數,無關鍵幀,因此任何幀都可獨立渲染, 且渲染中斷後可從停止處繼續。 - 兩階段渲染。
python scripts/blender/film.py plates,接著... layers。詳見下方。 - 合成。
python scripts/post/comp.py out.mp4 --draft用於快速檢查(每隔 6 幀), 然後移除--draft。調整結尾時使用--only-ending。 - 觀看成品。 在每個疊加文字的中間點擷取靜態幀檢查:文字是否清晰、文字所指的物體是否
出現在畫面中、鏡位之間是否有突兀感。修正後僅重新渲染受影響的鏡位(刪除其在
layers/中的檔案)。
兩階段渲染
擬真草地渲染很慢。移動物件則相對便宜。因此它們被分開渲染。
- Plates(場景層)。 每個鏡位一張完整場景的靜態幀(草地、道具、天空),範例中為 1280x720 解析度、36 個樣本。 光源變化的鏡位需要兩張 plates,合成器會交叉淡入淡出。
- Layers(動態層)。 僅包含移動的物件,背景透明,解析度與樣本數較低。 地面作為陰影捕捉器,使物件仍能投射陰影。靜態道具作為遮擋物,使物件 能正確從其後方穿過。天空保留以提供光源,但對攝影機隱藏。
- 合成器。 將 layer 疊在 plate 上,然後為每個鏡位添加緩慢的 2D 推近或平移以模擬攝影機運鏡。 鎖定的 3D 攝影機正是 plates 可重複使用的關鍵。
三項機制可降低成本:
- 循環。 如果鏡位是穩定流動,使運動變成週期性(間距 0.84 公尺,速度 0.84 公尺/秒,每秒重複一次),
並只渲染一個週期。
film.py與comp.py中的LOOP列表了這些鏡位。 - 隔幀渲染(On twos)。 圖層每隔一幀渲染一次(
STEP = 2)並保持顯示。它呈現出 停格動畫的風格,適合小巧的方塊物件。 - 續傳。 如果檔案已存在,則跳過該幀的渲染。
規模參考:範例影片(51 秒 3D 加上 12.5 秒結尾)需要 8 張 plates 與 456 幀 layers。 它完全在 CPU 上完成渲染。
2D 結尾
comp.py 直接繪製結尾,無需 Blender。一個 64x36 網格、使用調色盤顏色的圓角方格,在最後一幀 3D 畫面上方飛入,
寬度為 6 欄,攝影機拉遠直到顯示全部 64 欄,接著一道對角波浪使每個方塊翻轉(垂直壓縮至零再恢復,並在
中點切換顏色)至其最終顏色。最終顏色來自 3x5 像素字型,因此方塊就變成了文字。
規劃文案時需注意的限制:最多四行,每行 12 個字元(11 個效果更好),支援大寫字母、
數字以及 . - / !。設定於 film.json 中的 ending 區塊,需指定網格列號與調色盤按鍵。
編輯 film.json
palette:七個十六進位顏色。primary(主要色)、accent(強調色)、warm(暖色)、soft(柔和色)、deep(深色)、paper(結尾背景色與預設方塊顏色)、alarm(表示「有問題」的顏色)。overlays:[開始時間, 結束時間, "文字", x],時間單位為影片秒數。x為可選項,介於 0 到 1 之間的 水平位置,用於當主體位於置中文字會遮蓋處時調整文字位置。使用\n表示換行。ending:方塊要拼出的台詞。font:疊加文字使用的 .ttf 或 .otf 字型路徑。若未指定,則依序嘗試使用 Inter、DejaVu、Helvetica 或 Arial。
鏡位持續時間設定在 film.py 與 comp.py 開頭的 SHOTS 中。請保持兩者一致。
設定
python -m venv venv && . venv/bin/activate
pip install bpy==5.3.0 numpy pillow # bpy 是 Blender wheel;需搭配相符的 Python 版本
# ffmpeg 必須在 PATH 環境變數中
TEST=1 python scripts/blender/film.py plates # 480x270,每個鏡位一幀,數分鐘完成
TEST=1 python scripts/blender/film.py layers
python scripts/post/comp.py draft.mp4 --draft
FILM_OUT=/some/dir 會將 plates/ 與 layers/ 寫入該目錄,而非目前資料夾。FILM_CONFIG
指向不同的 film.json。GRASS_NEAR 與 GRASS_MID(百分比)可疏化草地。
若使用桌面版 Blender 而非 wheel 版本:blender -b -P scripts/blender/film.py -- plates。
可能耗費大量時間的陷阱
- 草長。 設定毛髮粒子系統的
normal_factor會重置hair_length。請最後再設定hair_length,否則每根草莖都會長達數公尺,使草地看起來像動態模糊。 - 父子關係。 設定父子關係會移動子物體,除非你設定了
matrix_parent_inverse。鉸接零件 會從道具上彈開。 - 天空。 將天空圖片貼在 UV 圓柱體上會變形。請使用大圓柱體上的鏡像面板,或是平坦的平面(如果攝影機從不平移)。 保持一個實體太陽以提供實際光源。
- 文字遮蓋主體。 將每個疊加文字與其下方的畫面比對。在移動攝影機前,先使用
x移動文字。 - 推近鏡頭會隱藏東西。 如果疊加文字提到了某個物體(例如「被擋住了!」),確認 2D 裁切後 該物體仍在畫面內。
- 顏色變淡。 在 AgX 色彩管理下的漆面顏色需要比品牌十六進位色更深的底色。螢幕 以及任何需要精確呈現顏色的物件應使用發射材質。
- 無 GPU。 按幀數預算:先計時一幀圖層的渲染時間,然後乘以總幀數,再據此降低解析度、樣本數或 鏡位長度。不要在未計時前就開始渲染。
- 容器重啟。 長時間渲染可能被中斷。依檔案存在與否跳過已渲染幀的機制是您的救星。
此流程不支援的功能
請事先向客戶明確說明這些限制,避免產生不切實際的期待。
- 移動的 3D 攝影機。鏡位是鎖定的,僅在頂層添加 2D 運鏡。真正的視差需要每幀都渲染場景, 這需要 GPU。
- 動態模糊與圖層上的 24 fps 運動。當硬體許可時,請提高樣本數,設定
STEP = 1並啟用render.use_motion_blur。 - 物件位於草地表面,而非嵌入其中,因為草地是 plates 的一部分。
- 音效。此影片設計為無聲播放。如有需要,事後可加入音樂與音效。
- 3D 世界中的螢幕、UI 或 Logo。刻意省略:將產品 UI 放在寫實場景中看起來很假。 請將產品視覺元素放在 2D 結尾或獨立的剪輯片段中。
最終品質輸出
兩個階段的解析度均為 1920x1080 或更高,128 個以上樣本並開啟降噪,GPU 渲染(OptiX 或 Metal),
STEP = 1,啟用動態模糊,並調高 comp.py 中的 W, H 以符合輸出尺寸。可按幀編號將畫面分割到
不同機器渲染;每一幀都是獨立的。