# 让 Claude Opus 5.5 写代码做一支 3D 宣传片：1250 行代码，没有一帧手动动画

先看成片：102 秒，60fps，中文旁白和字幕。

https://img.leeguoo.com/media/2a4bad30-a008-48db-98a9-5beb68e3bfa3/motion-use-promo.mp4

画面里每一个物体、每一次镜头移动、每一个音符，都是代码算出来的。没有用 AE，没有关键帧动画，没有素材库，也没有用文生视频模型。做这件事的是跑在 Claude Code 里的 Claude Opus 5.5，渲染用的是我们自己开源的 [motion-use](https://github.com/leeguooooo/motion-use)。

## 我给了什么

一句需求：用 three.js 给 motion-use 做一支一到两分钟、带旁白、讲原理和能做什么的宣传片。中途我只反馈过一次：第一帧是黑屏，README 播放器拿它当封面会很难看。它把第 0 帧改成了完整的开场画面。

## 它做了什么

**先核实，再写稿。** 旁白里每一句关于 motion-use 的说法，它都先去仓库源码里找出处：渲染器怎么逐帧定位、字体怎么裁剪、验收测什么。出处写在[导演记录](https://github.com/leeguooooo/motion-use/blob/main/examples/motion-use-promo/DIRECTOR.md)里。

**旁白决定时间线。** 先写 9 段旁白，生成语音、量出每段的实际时长，再按时长定镜头窗口。motion-use 的规则很严：旁白超出镜头会直接渲染失败，不会帮你截断。

**一条线讲完整个故事。** 开场那句需求落到地上，熔成一条发光的时间线。之后分镜卡沿着它立起，播放头在上面来回拖，帧从它上面升起被并行截取，旁白块装进它的镜头窗口，成片沿着它穿过验收扫描环。上一支作品里的毛毡小怪物当向导。

**3D 场景约 1000 行 three.js**：镜面地板加黑漆层，毛毡材质用 sheen 加半透明绒毛壳层，Bloom 做光晕，所有姿态都是时间的纯函数，任意时刻都能单独算出那一帧。

**配乐和音效是 Python 合成的波形**：96 BPM 的底，打字、快门、报错、通过提示都对着画面事件的时间点放，旋律只放在旁白的空隙里。

## 它自己抓到的问题

这部分最有意思。它不是写完就交，而是反复抽帧、看图、改：

- 第一版几乎每段都取景太远、字太小，分镜卡被 Bloom 吹成白块。
- 胶片右半边的帧消失了，但地板倒影里还看得到。它判断是半透明底板的排序把帧盖住了，固定绘制顺序后修好。
- 镜头在每个关键帧都会停一下，导致开场有 0.8 秒画面静止。它把插值改成连续的。
- 上一支片子里，草稿有约 30 帧出现黑色方块。它查出是个别像素算出了 NaN，被 Bloom 模糊扩散成一整块，于是在后期链最前面加了按位检测的清洗步骤。这个修复也沿用到了这支片。

交付前，motion-use 会解码整部成片，实测时长、帧率、响度，并检查旁白有没有真的混进去（按镜头做波形相关性比对）。这支片：0 个故障帧，9 段旁白全部检测通过，响度 -14.5 LUFS。

## 没做到的

- 旁白是 AI 语音（edge-tts）。
- 它听不见声音，配乐只做了频谱和响度测量，听感要人来判断。
- 目前只有中文版。

## 自己试试

motion-use 是开源的，装好后让你的 coding agent 读它的 skill，就能用同样的流程出片：

```bash
curl -fsSL https://raw.githubusercontent.com/leeguooooo/motion-use/main/install.sh | sh
motion-use doctor
```

这支片的完整源码在 [examples/motion-use-promo](https://github.com/leeguooooo/motion-use/tree/main/examples/motion-use-promo)，B 站版本在[这里](https://www.bilibili.com/video/BV1yhpe6bEwt)。
