3D 特效與 Shader:讓影片有電影感
用 Three.js + Remotion 做 3D 旋轉物件、用 GLSL shader 做光暈、用 Lottie 做向量動畫、整合 Figma 設計稿。進階視覺特效全包。
成品預覽
15 秒的電影感示範:CSS 3D 立方體旋轉、粒子浮動、鏡頭光暈掃過、CINEMATIC 大字配色差效果(chromatic aberration)加多層發光。這個 demo 全部用純 CSS + SVG 做出來,展示的是「電影感」視覺效果的組成元素——真實專案可以換成 @remotion/three 做真的 3D。
這篇會做出什麼
一支 10 秒電影感片頭,整合 Remotion 生態中所有進階視覺工具:
- Three.js:一個旋轉的 3D 立方體(貼自家 Logo 當材質)
- GLSL Shader:背景光暈扭曲(noise + 顏色混合)
- Lottie:AE 匯出的向量動畫點綴
- Light Leaks:電影感的光斑瑕疵
- Starburst:星芒閃光
- Figma 匯入:從 Figma 直接貼 SVG 進 Remotion
做完後你會理解:Remotion 不是「React 寫動畫」,是「React 把所有動畫工具串起來」。
前置知識
- T3 YouTube 片頭動畫
- 會一點 Three.js 最好(但沒有也能跟)
Step 1:安裝 Three.js 整合
Claude Code:
安裝 Remotion 的 Three.js 整合套件:
npm install @remotion/three three @react-three/fiber
然後新增 Composition "CinematicIntro":
- 1920x1080 fps 30 durationInFrames 300
- 背景 #000
@remotion/three 幹嘛?
它提供一個 <ThreeCanvas> 元件,把 React Three Fiber 接進 Remotion 的渲染管線——讓 3D 場景的時間軸跟 Remotion 的 useCurrentFrame() 同步。
💡 Three.js 整合的完整說明在 /docs/third-party。
Step 2:放一個旋轉立方體
在 CinematicIntro.tsx:
1. 用 <ThreeCanvas width={1920} height={1080}>
2. 裡面放:
- ambientLight + pointLight
- 一個 <mesh> 用 boxGeometry
- material 用 meshStandardMaterial
3. 立方體每幀旋轉:
用 useCurrentFrame() 算 rotation
rotation={[frame * 0.01, frame * 0.02, 0]}
4. 相機位置 [0, 0, 5]
這一步完成後 Studio 裡會看到一個旋轉的白色立方體。
Step 3:把 Logo 貼到立方體當材質
用 Remotion 的 staticFile() 載入 logo 當 Three.js 材質:
1. 從 three 套件 import TextureLoader
2. 用 useLoader(TextureLoader, staticFile("brand/logo.png"))
3. 材質改成 meshBasicMaterial map={texture}
4. 立方體六面都會貼 Logo
為什麼用 staticFile()?
Three.js 預設用 URL 載入 texture——在 Remotion 的 renderer 環境,必須用 staticFile() 才能正確解析路徑。
Step 4:加 Shader 背景
這是本篇最酷的一段。Shader 是 GPU 上跑的小程式,能做傳統 CSS 做不到的效果。
用 @remotion/shaders 加背景光暈扭曲:
npm install @remotion/shaders
然後:
1. 寫一個 fragment shader(GLSL):
- 用 iTime 做時間動畫(跟 useCurrentFrame() 同步)
- 用 simplex noise 做扭曲
- 顏色混合深藍到紫
2. 用 <Shader> 元件播 shader
3. 把 shader 放在 Three 場景之後(z-index lower)
Shader 基礎概念:
iTime:每幀遞增的浮點數,做動畫用fragCoord:像素座標,決定每個像素的顏色- Fragment shader 對每個像素跑一次
💡 Shader 完整教學、noise 函式、範例在 /docs/shaders。
Step 5:加 Lottie 動畫
Lottie = After Effects 匯出的 JSON 動畫。很多設計師會做好 Lottie 檔給你用。
安裝 @remotion/lottie:
npm install @remotion/lottie
把一個 Lottie JSON 放在 public/animations/sparkle.json
在 CinematicIntro 加 Lottie:
1. import { Lottie } from "@remotion/lottie";
2. <Lottie
animationData={require("../../public/animations/sparkle.json")}
style={{ width: 400, height: 400 }}
/>
3. 用 <Sequence from={60}> 控制出現時機
Lottie 的優勢:向量動畫,不受解析度限制。設計師用 AE 做好後匯出 JSON,你直接放 Remotion 裡,動畫一模一樣。
💡 Lottie 整合與 After Effects 工作流在 /docs/after-effects。
Step 6:Light Leaks 光斑瑕疵
電影感來自「瑕疵」——鏡頭漏光、底片刮痕、畫面抖動。Remotion 有現成的 light leaks:
加 @remotion/noise 做電影光斑:
npm install @remotion/noise
1. 在最上層加一個半透明的 noise 層
2. 用 <Noise
type="perlin"
scale={2}
frequency={0.5}
opacity={0.15}
blendMode="screen"
/>
3. 這會在整個畫面上疊一層動態的電影顆粒
💡
noise-visualization、light-leaks、starburst的範例在 /docs/noise-visualization、/docs/light-leaks、/docs/starburst。
Step 7:Starburst 星芒
在 Logo 的四個角加星芒閃光:
1. 從 @remotion/shapes 用 <Star> 元件
2. 每個星芒用 spring() 從 scale 0 彈跳進場
3. 星芒用白色 + 黃色漸層
4. blendMode: "screen" 讓它疊在背景上發光
Step 8:從 Figma 貼 SVG
設計師用 Figma 畫了個裝飾圖形?直接 Copy as SVG 貼進來:
在 Figma 選中圖形 → Copy as SVG → 貼到新檔案:
src/assets/decoration.tsx
把 <svg> 包進 export default function Decoration() { return <svg>... </svg> }
然後在 CinematicIntro 用:
<Decoration style={{ position: "absolute", top: 100, left: 100, width: 300 }} />
搭配 spring() 做出現動畫。
為什麼 SVG 好?:向量縮放不糊、可以用 CSS 控制顏色、檔案小。Remotion 完全支援。
💡 Figma → Remotion 的工作流完整說明在 /docs/figma。Spline 整合在 /docs/spline。
Step 9:影片當 Three.js 材質
最酷的技巧:把影片當 3D 物件的材質。
在立方體的一面貼影片當材質:
1. 用 @remotion/three 的 <VideoTexture>
2. <mesh>
<planeGeometry />
<meshBasicMaterial>
<VideoTexture src={staticFile("clips/background.mp4")} />
</meshBasicMaterial>
</mesh>
3. 這個 plane 會播放影片
應用場景:做「影片牆」「電視機裡播影片」「3D 空間裡的 monitor」。
💡
video-as-threejs-texture的完整範例在 /docs/video-as-threejs-texture。
Step 10:渲染
渲染 CinematicIntro:
- 1920x1080 H.264
- CRF 16(高品質,因為有 shader)
- GPU 加速渲染(concurrency 2 避免爆顯卡)
3D + Shader 渲染會很慢。10 秒影片可能要 5~10 分鐘。渲染時機器風扇會轉很大聲,正常。
完成!回顧學到的概念
| 概念 | 用在哪 |
|---|---|
@remotion/three 整合 | Step 1~3 |
| Three.js + useCurrentFrame 同步 | Step 2 |
staticFile() 載入 3D 材質 | Step 3 |
| GLSL fragment shader | Step 4 |
@remotion/lottie 向量動畫 | Step 5 |
| Noise / light leaks | Step 6 |
| Figma → SVG 貼上 | Step 8 |
| 影片當 3D 材質 | Step 9 |
本篇涵蓋的官方文件
- /docs/shaders — GLSL shader
- /docs/third-party — Three.js / Lottie 整合
- /docs/video-as-threejs-texture — 影片當 3D 材質
- /docs/noise-visualization — Noise 視覺
- /docs/light-leaks — 光斑瑕疵
- /docs/starburst — 星芒
- /docs/figma — Figma 整合
- /docs/spline — Spline 整合
- /docs/after-effects — AE 整合
常見問題
Q:Three.js 場景在 Remotion 裡看起來跟 r3f demo 不一樣?
A:因為 Remotion 的 <ThreeCanvas> 預設 frameloop="never"——Remotion 決定什麼時候渲染,不是 r3f 的 requestAnimationFrame。時間用 useCurrentFrame() 驅動。
Q:Shader 在 Studio 看得到但渲染出來是黑的?
A:通常是 WebGL context 在 Puppeteer 裡沒開 GPU。在 remotion.config.ts 加 Config.setChromiumDisableWebSecurity(true) 和 Config.setGl("angle")。看 /docs/chromium-flags。
Q:Lottie 動畫播起來卡卡的?
A:Lottie JSON 太大(> 500KB)會在 Remotion 的 Render 環境裡拖慢。優化:用 lottie-api 先移除不必要的 keyframes,或改用 SVG + CSS 手寫。
Q:可以用 Three.js 的 glTF 3D 模型嗎?
A:可以。用 useGLTF hook 載入 .glb 檔案。但 Remotion 渲染時 Puppeteer 載入 glTF 的 loader 要手動注入,有點工。簡單模型用 <boxGeometry> / <sphereGeometry> 夠用。
下一步
- T13:進階渲染——透明影片、GIF、編碼格式 — 把這支片頭輸出成不同格式
- T20:打造影片 SaaS API + Docker 部署 — 把這種重計算的渲染搬到伺服器
有問題歡迎到 FB 社群 討論!