Blender 产品视频
一种方法及可运行的示例,用于制作长度为45至75秒、在静音状态下也能被理解的产品影片。 一个逼真的场景(草地、木门、真实天空)承载一个视觉隐喻。简短的文字叠加层诉说着画面无法传达的信息。影片最终变为一个由彩色方块组成的平面网格,方块翻转拼出标题和行动号召。
一切都是代码:场景、动画、合成。无需打开图形用户界面。
文件夹内容
| 路径 | 说明 |
|---|---|
film.json | 调色板、带时间戳的叠加文字、结尾文字。请先编辑此文件。 |
scripts/blender/build.py | 场景:带有毛发粒子草地的山坡、栅门、磨砂方块、天空、雾效、渲染设置。 |
scripts/blender/mascot.py | 示例角色:一个可以坐在栅栏柱上的体素猫头鹰。 |
scripts/blender/film.py | 镜头、相机、逐帧动画。渲染 plates 和 layers。 |
scripts/post/comp.py | 合成器:底板+图层、2D摄像机运动、文字、调色、2D方块结尾、ffmpeg编码。 |
assets/ | 两张天空图(金色、阴天)。请替换为您自己的。 |
examples/ | 使用此流程制作的影片的帧画面。 |
示例影片是“栅门”:相同的方块以稳定的速度穿过一扇打开的栅门,然后以各种大小排列,最后蜂拥而至。栅门关闭,之后方块被放行、计数或阻止。将其视为结构参考,然后用适合产品的隐喻替换当前隐喻。
工作流程
按顺序执行以下步骤。在花费渲染时间进行下一步之前,确保每一步都获得批准。
- 简报。 各用一句话说明:目标受众、问题、转折点、承诺、行动号召。确定时长(45至75秒)、宽高比以及播放位置。假设静音播放。
- 隐喻。 选择一个物理图像代表问题,再选择一个对图像的改变代表产品。一个地点、一个主要道具、一种运动物体。如果需要解释,请重新选择。
- 镜头表。 6至8个镜头。每个镜头需注明:时长、运动内容、叠加文字(不超过8个词,一个概念)、相机位置和镜头。问题部分使用冷调的阴天光线,产品部分使用暖色调光线。以表格形式呈现并获得批准。
- 角色(可选)。 一个小主角可以为视线提供焦点。先在草图上提供3到4个选项,然后再建模。大小要适配场景:应能放在主要道具上。用简单的基本体构建(猫头鹰由1厘米的立方体组成)。
- 代码构建场景。 调整
build.py。保持单位以米为单位,主要道具位于原点。每个镜头用低采样率渲染一帧静帧,并在制作动画前逐一检查。 - 动画。 在
film.py中,每个镜头都有setup_X(创建一次对象)和update_X(t)(将每一帧的所有内容放置在影片的第t秒)。纯时间函数,无关键帧,因此任何帧都可以单独渲染,渲染崩溃后可以从停止的地方恢复。 - 两阶段渲染。
python scripts/blender/film.py plates,然后... layers。见下文。 - 合成。
python scripts/post/comp.py out.mp4 --draft进行快速检查(每隔6帧渲染),然后去掉--draft。在调整结尾时使用--only-ending。 - 观看。 在每段叠加文字的中点拉取静帧,检查:文字是否清晰可读,文字所指的对象是否在画面中可见,镜头切换时是否有跳变。修正并仅重新渲染受影响的镜头(删除其在
layers/中的文件)。
两阶段渲染
逼真的草地渲染很慢。移动物体则很便宜。因此它们分开渲染。
- 底板(Plates)。 每个镜头一帧完整的场景(草地、道具、天空),示例中为1280x720,采样36。一个光线变化的镜头需要两张底板,由合成器进行交叉渐变。
- 图层(Layers)。 仅包含移动物体,透明背景,较低分辨率和采样率。地面是阴影捕捉器,因此物体仍能投射阴影。静态道具是遮罩体,因此物体可以正确从它们后面穿过。天空保留用于照明,但对相机隐藏。
- 合成器(Compositor)。 将图层放置在底板上,然后通过每个镜头的缓慢2D推拉或漂移来模拟相机运动。锁定的3D相机是使底板可复用的关键。
三件事能降低成本:
- 循环。 如果镜头是稳定的流,使运动具有周期性(间距0.84米,速度0.84米/秒,每秒重复一次),并只渲染一个周期。
film.py和comp.py中的LOOP列出了这些镜头。 - 双帧渲染。 图层每隔一帧渲染(
STEP = 2)并保持。这看起来像定格动画,适合小巧的块状物体。 - 断点续传。 如果文件已存在,则跳过该帧的渲染。
作为规模参考:示例影片(51秒3D加上12.5秒结尾)共8个底板和456个图层帧。完全在CPU上渲染完成。
2D结尾
comp.py 直接绘制结尾,无需Blender。一个64x36的调色板圆角方块网格,在最后一帧3D画面上以6列宽度飞入,相机后拉直到所有64列显示出来,然后一个对角波浪翻转每个方块(垂直压缩到零再恢复,在中点交换颜色)到其最终颜色。最终颜色来自3x5像素字体,因此方块组成了文字。
规划文案时需注意的限制:最多四行,每行12个字符(11个看起来更好),支持大写字母、数字和 . - / ! 字符。在 film.json 的 ending 部分设置,包含网格行和调色板键。
编辑 film.json
palette:七个十六进制颜色。primary、accent、warm、soft、deep、paper(结尾背景和默认方块色)、alarm(“出问题”颜色)。overlays:[开始时间, 结束时间, "文字", x],时间以影片秒为单位。x是可选的,0到1之间的水平位置,用于当主题位于居中文字会覆盖的位置时。使用\n表示换行。ending:方块拼出的文字行。font:叠加文字所用字体的 .ttf 或 .otf 文件路径。如果找不到,则依次回退到 Inter、DejaVu、Helvetica 或 Arial。
镜头时长在 film.py 和 comp.py 顶部的 SHOTS 中定义。请保持两者一致。
设置
python -m venv venv && . venv/bin/activate
pip install bpy==5.3.0 numpy pillow # bpy 是 Blender wheel 包;需要匹配对应的 Python 版本
# ffmpeg 必须在 PATH 中
TEST=1 python scripts/blender/film.py plates # 480x270,每个镜头一帧,几分钟完成
TEST=1 python scripts/blender/film.py layers
python scripts/post/comp.py draft.mp4 --draft
FILM_OUT=/some/dir 会将 plates/ 和 layers/ 写入指定目录而非当前文件夹。FILM_CONFIG 指向不同的 film.json。GRASS_NEAR 和 GRASS_MID(百分比)用于稀疏草地。
如果使用桌面版 Blender 而非 wheel 包:blender -b -P scripts/blender/film.py -- plates
可能浪费大量时间的陷阱
- 草地长度。 设置毛发粒子系统的
normal_factor会重置hair_length。应最后设置hair_length,否则每根草都会有几米长,整个田野看起来像运动模糊。 - 父子关系。 设置父子关系会移动子对象,除非你设置了
matrix_parent_inverse。铰链部件会从道具上跳开。 - 天空。 在UV圆柱体上使用天空图会导致拉伸。如果相机从不摇摄,可以使用大圆柱体上的镜像面板或平坦平面。保持一个真实的太阳光源用于实际照明。
- 文字遮挡主体。 检查每段叠加文字与其下方的帧画面。在移动相机之前,先用
x移动文字。 - 画面推进会隐藏东西。 如果叠加文字提到了某个物体(例如“被阻止。”),请确认2D裁剪后该物体仍然可见。
- 颜色洗白。 在AgX色彩管理下,涂漆表面需要比品牌十六进制颜色更暗的基色。屏幕和任何需要精确显示的颜色应设为自发光。
- 无GPU。 按帧预算:计时单个图层帧,然后乘以总数,再通过降低分辨率、采样率或镜头长度来调整,直到预算可行。不要开始渲染未经时间预估的任务。
- 容器重启。 长时间渲染可能被中断。文件存在则跳过的检查机制就是你的救命稻草。
此流程不包含的功能
在用户期待这些功能之前,请直接告知他们。
- 移动的3D相机。镜头是锁定的,顶部叠加2D运动。真正的视差需要每帧渲染场景,这需要GPU。
- 运动模糊和图层上的24fps运动。当硬件允许时,提高采样率,设置
STEP = 1并启用render.use_motion_blur。 - 物体位于草地之上,而非陷入其中,因为草地包含在底板中。
- 声音。影片设计为无声运行。如果需要,可以后加上音乐和音效。
- 3D世界中的屏幕、用户界面或标志。有意省略:逼真场景中的人造界面看起来很假。将产品视觉元素放在2D结尾或单独的剪辑中。
最终高质量输出
两阶段渲染均使用1920x1080或更高分辨率,128+采样并开启降噪,GPU渲染(OptiX或Metal),STEP = 1,开启运动模糊,并将 comp.py 中的 W, H 提高以匹配。按帧编号将帧分配到多台机器上渲染;每一帧都是独立的。