不用摄影机也能拍一镜到底
从城市上空落进一扇窗,一路钻进芯片。没有摄影机也没有模型文件,是 AI 写的 Three.js 网页,提示词在下面。
30 秒一镜到底
<role>
你是 3D 动画导演,也是创意程序员。用一个独立的 HTML 文件 + Three.js(ES 模块,importmap 引本地的 three)做一段 30 秒、1920×1080 的一镜到底,最后拍成 MP4。不用任何外部图片、3D 模型文件或网络请求,所有东西用代码搭。
</role>
<direction>
题目:你发给 AI 的一句话,跑到哪儿去了(示意,不追求真实)。风格:低多边形积木风的小城,黄昏,暖色窗光 + 冷色机房 + 一个荧光黄绿的光点贯穿全片。
镜头每动一下都要有理由;禁止:全程高空俯瞰、匀速绕圈、突然转向、大幅摇晃、满屏金色粒子、只有环境光的平光(塑料感)、用浓雾盖住空场景。
</direction>
<structure>
0–5 秒 绕:从城市上空侧着绕下来,夕阳在楼后(逆光),交代地点。
4.5–8 秒 推:推进主角楼的一扇窗,屋里台灯、书架、一台笔记本,屏幕上一句话打出来、发送。
8–10.5 秒 光点从笔记本出发,沿一根线缆爬过窗台、顺着外墙往下,镜头跟着往下摇。
10.5–13.5 秒 跟:镜头贴地追着光点沿马路飞,路灯一盏盏掠过,远处是一座亮着蓝色灯带的数据中心。
13.5–17.5 秒 推:进门,机房过道左右对称,两排机柜的指示灯在闪,沿过道往里推。
17–19 秒 冲:光点钻进一台机柜,镜头转过去冲进显卡上的芯片,金线越来越亮,闪白。
19–25.4 秒 芯片里面:14 层点阵(每层 40×24 个点),信号一层层往里传、亮起一部分点和连线;镜头先贴着信号往前冲,再侧着拉出来看清一整摞;最后一层冒出一个亮点冲向镜头,闪白。
25.4–30 秒 拉:回到笔记本屏幕前,回答一行行出来,镜头一路拉出窗外、升到高处,回到开场那座城。
</structure>
<build>
1. 页面暴露 window.render(t):画面只由 t 决定(光点位置、车、指示灯闪烁、屏幕上的字、镜头全部是 t 的函数),不用 requestAnimationFrame、不用 Clock;随机数带固定种子。
2. 镜头:每一段是一个小函数 rig(t) → { pos, look, fov };相邻两段在约 1 秒的交界里把位置、朝向、视角线性混合;每段内部用慢起慢停的缓动。
3. 线缆是一条 CatmullRomCurve3(centripetal),光点按「时间 → 第几个控制点」的关键帧(单调三次插值)在曲线上走,后面拖一串越来越淡的发光精灵当拖尾。
4. 光:一盏低角度的夕阳 DirectionalLight 投影子 + 半球光 + 一点正面冷色补光;天空是一个大球的着色器渐变(地平线橘粉 → 头顶深蓝)+ 星星;FogExp2 做空气透视;UnrealBloomPass 泛光 + ACES 色调映射。
5. 省性能:楼的窗户是随机亮格子的 CanvasTexture 当 emissiveMap(只亮约两成多),路灯的地面光圈是叠加混合的径向渐变贴图,不点真的灯;机柜和指示灯用 InstancedMesh。
6. 拍摄:起一个本地静态服务器(ES 模块不能从 file:// 加载),Playwright 打开页面,逐帧调用 render(i / 30) 并截图(900 张),喂给 ffmpeg 压成 MP4。没有显卡的机器上 Chromium 会自动用 SwiftShader 软件渲染,能跑,约 1 秒一帧。
7. 配乐用 Python numpy 合成:和弦铺底随场景换和声,光点出发后加拨弦琶音,机房加底鼓,进芯片和回屏幕各有一次呼啸 + 低音,穿过每层网络有一声小铃。
8. 留开关 setup({ lights:'flat', fog, bloom, god, cam }):关灯光/雾/泛光做对比;god 是上帝视角(画出镜头走过的路和它的视锥);cam 是单独的练习镜头(绕圈、推、变焦、晕眩镜头)。
</build>
<gotchas>
- 每做完一段就渲 3 张静帧自己看:镜头有没有卡进楼里、主体够不够大、亮的东西有没有糊成一片。
- 光点贴着墙走时,光晕精灵会被墙切掉一半(变成吃豆人):线缆离墙远一点。
- 窗户亮灯太多会像一块 LED 屏,夜景要少。
</gotchas>
- 我用的是 Claude Opus 5.5,在 Claude Code 里做的。
- 镜头好不好看,关键是分成几小段(绕、推、出窗、追……),段和段之间用一秒左右混过去,就看不出接缝。
- 想换题目,改 direction 和 structure 两段。
- 打开时要联网(Three.js 从公共 CDN 加载);比较吃显卡,手机上可能会卡。
先搭一个小片场练手
用 Three.js 做一段 25 秒、1920×1080 的教学动画,window.render(t) 驱动,奶白色地面 + 细网格,道具带黑色描边: 0.3 秒 搭景:方块、球、圆柱、圆锥依次从空中掉下来弹一下(只有均匀的环境光,看起来很平); 5 秒 打光:一个卡通小太阳出现,虚线连到场景中心,换成一盏斜上方的平行光,出现柔和的影子; 9.6 秒 摆机位:一台黑色小摄影机模型飞进来停在斜前方,用 CameraHelper 画出它的四棱锥; 13.7 秒 按快门:闪白,切到这台摄影机看到的画面,四角加取景框和「● CAM 1」; 18 秒 这台摄影机一边推近一边绕着道具转大半圈; 22.6 秒 切回旁观视角,用一根红色的管子画出它刚才走过的路。
- 第一次玩 3D 先用这个小的:25 秒把搭景、打光、摆机位、运镜四步走一遍。