3D 缩放解释器
一种比任何图表都更能诠释尺度的格式:从一个众所周知的物体开始,无剪切飞入其中,屏幕上保持一个数字告诉观众他们走了多远,最后以一个出人意料的事实结束。此技能的参考结果是“没有什么是真正锋利的”:一片刀片、26 次对半、一个铁原子,以及一条说明其边缘仍有大约 300 个原子宽的提示。
assets/template/ 就是那个完成的项目。从它而非空文件开始:那些困难的部分(在不损失精度的情况下缩放八个数量级、随尺度变化的细节、景深、确定性渲染器)已经在那里解决,并经过多轮迭代才正确。
公式
保持全部五个。每一个都在起作用。
- 一个连续镜头。 关键在于观众永远不会迷失方向。剪辑会重置他们对尺度的感知。
- 一个实时测量值。 一条固定在主体上的细条,一个每帧变化的数字,一个对半(或加倍)计数,以及两三个关于当前视野的词语。这条细条是观众唯一需要读取的内容,因此它必须诚实:其在场景中的长度确实就是显示的数字。
- 主体在每个尺度下改变特征。 抛光变成磨痕,然后变成碎屑,再变成晶粒,接着变成圆边,最后变成原子。如果表面在三秒钟内看起来一样,那么缩放就会被视为什么都没发生。
- 比例参考。 随着缩放经过每个尺寸,一个该尺寸的常见物体放置在主体旁边,并标注其名称和大小:盐粒、头发、红细胞、细菌、病毒、晶体管、抗体、DNA。它们将抽象数字变成“比病毒还小”。
- 一个回报。 快速拉回起点,展示这次旅程的唯一数字。
工作流程
1. 建模前先研究
视频只有在真实时才有价值。查阅实际尺寸(网络搜索,尽量使用主要来源),并记录主体和每个比例参考物体的尺寸、来源以及你简化的地方。几何图形随后根据这些数字构建,因此画面不会偏离事实。最后向用户报告来源和简化之处;他们会被询问。
选择 6 到 9 个比例参考物体,每个至少比前一个小约 3 倍。更接近的话它们的标签会冲突;相隔 30 倍以上则屏幕会空置数秒。
2. 在需要时展示计划
如果用户要求先看计划,或者简报留下了真正的选择空间(画外音还是静音、语言、回报是什么),请给出一个简短的表格:时间、尺度、视野内容、比例参考物体。否则直接进行;没人要求的计划只会延迟首次渲染。
3. 搭建项目
cp -r <skill>/assets/template <project>/ && cd <project> && npm install
node render.mjs --stills 1,10,20,30,40
第二条命令应打印 GPU 名称并写入五张 JPEG 文件到 out/。如果报告的是 SwiftShader 或 llvmpipe,则渲染在 CPU 上进行,将耗时数小时:在进一步操作前修复 GPU 标志(参见 references/pitfalls.md)。
4. 调整场景
main.js 是一个文件,分节编写。在进行任何结构性更改前,先阅读 references/techniques.md;它解释了每个部分为何如此构建。对于新主题通常需要更改的内容:
main.js 中的节 | 需要替换的内容 |
|---|---|
| constants | 以米为单位的物理数据、起始大小 L0、对半次数 HMAX、时间线 |
| subject surface | 横截面 prof()、轮廓裁剪、表面特征表 FEATS(波长、类型、强度) |
| finest scale | 原子晶格(或最后一个阶段由什么构成) |
| things for scale | addObj(name, sizeText, sizeInMetres, geometry, material, placement) 列表 |
| overlay | LABELS(每个缩放级别的视野内容)、最终字幕 |
| camera keys | 作为缩放级别函数的 K_AZ、K_EL、K_TY、K_D、K_AP |
对于不同形状的主体(芯片、叶片、纸张),保留机制,替换轮廓和特征。对于向外缩放,反向运行相同的时间线并说“加倍”。
5. 在渲染影片前先查看静态图像
在时间线上渲染 8 到 10 张静态图像,用 ffmpeg 将它们拼贴成联系表并阅读。然后修复你所看到的问题并重复。这一循环是质量的来源;参考影片第一个版本中的每个问题都在静态图像中可见,而没有一个问题在代码中可见。特别检查:
- 曝光。 第一遍几乎总是过曝。金属应为大部分暗色,带有明确的亮点。
- 任何被帧边缘裁切的内容, 尤其是靠近顶部的比例参考物体。
- 标签位于亮区或彼此重叠。 将测量标签保持在空黑色区域。
- 每个阶段是否如标签所述。 如果标签说“晶粒”而画面是条纹,则其中一个是错的。
- 第一帧和最后一帧, 因为它们是缩略图和点睛之笔。
ffmpeg -y -i a.jpg -i b.jpg -i c.jpg -i d.jpg -filter_complex "[0][1]hstack[t];[2][3]hstack[u];[t][u]vstack,scale=1920:-1" sheet.jpg
6. 渲染并验证结果
node render.mjs --full --o video.mp4 # 如果有旁白则添加 --audio vo.wav
在后台运行;一个 45 秒的 1080p 影片在独立 GPU 上需要几分钟。然后检查文件本身,而非你之前制作的静态图像:探测时长和大小,提取概览网格,从繁忙段落提取六帧连续帧以查找闪烁。精细程序性细节压缩不佳,因此预计文件较大,并在需要时制作较小的副本:
ffmpeg -i video.mp4 -vf "fps=1/3,scale=640:-1,tile=4x4" -frames:v 1 overview.jpg
ffmpeg -ss 13 -i video.mp4 -vf "crop=960:540:480:270,tile=3x2" -frames:v 1 consecutive.jpg
ffmpeg -i video.mp4 -vf scale=1280:720 -c:v libx264 -preset slow -crf 25 -maxrate 4200k -bufsize 8400k small.mp4
明确说明你验证了什么以及没有验证什么。帧网格证明画面正确;它们不能证明运动感觉正确,因此应说明用户应观看它。
默认设置
- 静音。 除非要求,否则无音乐、无音效、无画外音。格式本身已足够,且参考影片也没有旁白。
- 文本仅包含数据和名称。 测量值、对半计数、视野内容、比例参考物体的名称和大小、一个最终数字。如果加入旁白,删除画外音已经提到的每个标签,因为同时阅读和聆听相同词汇会分散注意力。
- 1920x1080、30 fps、40 到 50 秒, 以 1.5x 渲染并缩小。对于竖屏视频,更改
W和H并重新检查每张静态图像;构图不会自动转移。 - 使用用户观众的语言的标签, 该语言不总是他们聊天时使用的语言。如果不清楚请询问。
添加画外音
仅在要求时。将脚本写成每行都属于一个阶段的短行,生成或接收音频,获取单词时间码(faster-whisper 效果很好),然后根据音频驱动缩放:缩放级别成为时间的关键帧函数,在解释某个阶段时停留,并在行之间移动。将音频传递给 render.mjs --audio。在每个停留期间让一些小事发生(光线扫过、物体到达、原子振动),否则暂停的缩放看起来像冻结。
参考文件
references/techniques.md- 模板的工作原理及原因:围绕焦点缩放、按尺度窗口化的程序性细节、球体冒充、景深、锚定在物理空间中的物体、确定性渲染器。在进行结构性更改前阅读。references/pitfalls.md- 已遇到的失败及其修复。当渲染看起来错误或工具表现异常时阅读。MASTER_PROMPT.md- 用于开始新视频的填充提示,以及适合该公式的主题想法。