Back to Remotion

3D Animation with ThreeCanvas

packages/template-prompt-to-motion-graphics/src/skills/3d.md

4.0.4572.1 KB
Original Source

ThreeCanvas Setup

Always wrap 3D content in ThreeCanvas and include proper lighting.

Incorrect (missing ThreeCanvas wrapper):

tsx
<mesh rotation={[0, frame * 0.02, 0]}>
  <boxGeometry args={[2, 2, 2]} />
  <meshStandardMaterial color="#4a9eff" />
</mesh>

Correct (proper ThreeCanvas setup):

tsx
import { ThreeCanvas } from "@remotion/three";

<ThreeCanvas>
  <ambientLight intensity={0.5} />
  <pointLight position={[10, 10, 10]} />
  <mesh rotation={[0, frame * 0.02, 0]}>
    <boxGeometry args={[2, 2, 2]} />
    <meshStandardMaterial color="#4a9eff" />
  </mesh>
</ThreeCanvas>;

Lighting Setup

Every 3D scene needs ambient + directional light for depth.

Incorrect (no lighting - objects appear flat/black):

tsx
<ThreeCanvas>
  <mesh>
    <sphereGeometry args={[1, 32, 32]} />
    <meshStandardMaterial color="red" />
  </mesh>
</ThreeCanvas>

Correct (proper lighting):

tsx
<ThreeCanvas>
  <ambientLight intensity={0.4} />
  <directionalLight position={[5, 5, 5]} intensity={0.8} />
  <mesh>
    <sphereGeometry args={[1, 32, 32]} />
    <meshStandardMaterial color="red" />
  </mesh>
</ThreeCanvas>

Frame-Based Rotation

Use frame directly for smooth continuous rotation.

tsx
const frame = useCurrentFrame();
const rotationY = frame * 0.02; // Adjust speed with multiplier

<mesh rotation={[0, rotationY, 0]}>
  <boxGeometry args={[2, 2, 2]} />
  <meshStandardMaterial color="#4a9eff" />
</mesh>;

Floating/Hovering Animation

Use sine wave on Y position for organic floating effect.

tsx
const frame = useCurrentFrame();
const floatY = Math.sin(frame * 0.1) * 0.3; // Amplitude 0.3, speed 0.1

<mesh position={[0, floatY, 0]}></mesh>;

Spring-Based Scale Entrance

Use spring() for bouncy 3D object entrances.

tsx
const scaleProgress = spring({
  frame,
  fps,
  config: { damping: 12, stiffness: 100 },
});

<mesh scale={[scaleProgress, scaleProgress, scaleProgress]}>
</mesh>;

Camera Positioning

Position camera at reasonable distance for scene visibility.

tsx
<ThreeCanvas camera={{ position: [0, 0, 5], fov: 75 }}>
</ThreeCanvas>