比特之外

Remotion 教程 09:用 Three.js 做 3D 产品展示视频

当视频里出现产品旋转、空间转场、3D 标题或立体图表时,DOM/CSS 很快会吃力。这个时候更合适的组合是:

three
@react-three/fiber
@remotion/three

Three 负责 3D 场景,Remotion 负责视频时间轴。

什么时候需要Three

优先考虑 Three 的场景:

  • 产品 360 度展示。
  • 手机、耳机、包装盒、设备模型展示。
  • 空间穿梭转场。
  • 3D 标题和立体 Logo。
  • 需要相机、灯光、材质的图表。

如果只是一个普通卡片入场动画,不需要 Three。DOM + Remotion 的 interpolate() 就够了。

3D 动画仍然由 frame 决定

在 Remotion 里用 Three,不代表把时间交给 Three。旋转角度、相机位置、材质参数仍然应该由 frame 推导:

const frame = useCurrentFrame();
const rotation = interpolate(frame, [0, 150], [0, Math.PI * 2]);

含义是:

第 0 帧   -> 旋转角度 0
第 150 帧 -> 旋转角度 2π,也就是转完一圈

然后把角度交给 3D mesh:

<mesh rotation={[0.45, rotation, 0.25]}>

这和 2D 动画原则完全一致:不是让 Three 自己跑时间,而是由 Remotion frame 算出这一帧的角度。

完整最小示例

下面是一个真实 3D 立方体。它不是图片,也不是 CSS 假 3D。

import React from "react";
import { ThreeCanvas } from "@remotion/three";
import { AbsoluteFill, interpolate, useCurrentFrame } from "remotion";
 
const ProductCube: React.FC = () => {
  const frame = useCurrentFrame();
  const rotation = interpolate(frame, [0, 150], [0, Math.PI * 2]);
 
  return (
    <>
      <ambientLight intensity={0.8} />
      <directionalLight position={[4, 5, 6]} intensity={1.6} />
 
      <mesh rotation={[0.45, rotation, 0.25]}>
        <boxGeometry args={[2.4, 2.4, 2.4]} />
        <meshStandardMaterial
          color="#2563eb"
          metalness={0.25}
          roughness={0.35}
        />
      </mesh>
    </>
  );
};
 
export const ThreeProductDemo: React.FC = () => {
  return (
    <AbsoluteFill
      style={{
        backgroundColor: "#f8fafc",
        display: "grid",
        placeItems: "center",
      }}
    >
      <ThreeCanvas width={620} height={520} camera={{ position: [0, 0, 7] }}>
        <ProductCube />
      </ThreeCanvas>
    </AbsoluteFill>
  );
};

ThreeCanvas 是 Remotion 和 React Three Fiber 的连接层。它让 Three 场景能进入 Remotion 的视频渲染流程。

真实项目通常还需要模型

教学示例用的是 boxGeometry,因为它足够展示 Three 和 Remotion 的连接方式。

真实产品视频一般会加载 glTF / GLB 模型,再控制相机、灯光、材质和关键帧。即便模型更复杂,原则仍然不变:

frame -> 相机位置 / 模型旋转 / 材质参数

性能注意点

Three 场景比 DOM 更重。做视频模板时要注意:

  • 模型面数不要过高。
  • 材质和贴图尺寸要合理。
  • 灯光数量不要失控。
  • 尽量让相机和模型运动可预测。
  • 单帧渲染先通过,再跑完整视频。

示例项目位置

这篇文章对应示例项目里的:

Composition: LessonThreeEcosystem
文件: src/lessons/ThreeEcosystem.tsx

运行示例项目后,可以尝试:

  1. [0, 150] 改成 [0, 75],观察旋转速度。
  2. 修改材质颜色。
  3. 修改相机位置 [0, 0, 7]

下一篇看 Skia:当你要做高级 2D 光效、路径和动态图形时,它比 DOM 更合适。