Communitygithub.com

Blender 无头动画

用 Python 在后台驱动 Blender:场景、材质、灯光、相机、关键帧、几何节点,以及 MP4 或图片序列。脚本是源头,blend 文件只是构建产物。

Blender 无头动画 是什么?

面向真实几何、光和运镜的通用三维动画技能。它先核对已安装的 Blender 版本,再无头运行,用 EEVEE 或 Cycles 出图。转台只是产品镜头、粒子和电影运镜之中的一种触发,不是唯一用途。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/aminghaseminia/blender-animation-skill/tree/HEAD/skills/blender-animation

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Blender 动画 — Python驱动的3D工作流

通过后台模式下的 bpy 驱动 Blender,使用可重新运行的脚本。将 .blend 文件视为脚本的构建产物:脚本是真相来源,文件是可交付物。

阅读 references/BLENDER-PLAYBOOK.md 了解架构和判断原则,以及 references/BLENDER-RECIPES.md 获取可直接复用的代码模式。请对照已安装的 Blender 版本验证每个 API 细节;Python API 在不同版本间会变化。

1. 首先验证环境

blender --version
blender --background --factory-startup --python-expr \
  "import bpy, sys; print('BLENDER', bpy.app.version_string); print('PY', sys.version.split()[0]); print('ENGINES', [e.bl_idname for e in bpy.types.RenderEngine.__subclasses__()][:5])"

规则:

  • bpy 属于 Blender 自带的 Python。永远不要 pip install bpy,也永远不要用系统 Python 运行场景脚本。
  • 使用 --python-exit-code 1 以便 Python 异常导致 shell 命令失败,而非静默成功。
  • 使用 --factory-startup 进行干净构建;切勿用它清除用户已打开的项目。
  • 每次渲染开始时记录 Blender 版本、渲染引擎、帧范围、分辨率、FPS 和输出路径。

2. 标准调用方式

# 从头构建场景并保存 .blend
blender --background --factory-startup --python-exit-code 1 --python blender/scripts/build_scene.py

# 修改现有项目
blender --background project.blend --python-exit-code 1 --python blender/scripts/update_scene.py

# 渲染已保存的动画
blender --background project.blend --render-anim

# 渲染单帧
blender --background project.blend --render-frame 120

# 安全渲染一段范围(图像序列)
blender --background project.blend --python-exit-code 1 --python blender/scripts/render_frames.py

长时间运行的作业请将输出重定向到 logs/,并且对于可能需要恢复的任何内容,始终优先使用图像序列。

3. 脚本架构

对于小型场景,从一个文件开始。当场景超过大约300行或包含多个镜头时,进行拆分:

blender/
  config.py          # fps, 帧范围, 分辨率, 调色板, 路径, 种子
  build.py           # 入口点:重置 → 设置 → 构建镜头 → 保存
  scene_setup.py     # 世界, 单位, 集合, 渲染设置
  geometry.py        # 基本体, 曲线, 参数化网格
  materials.py       # 节点构建器, 可复用的材质工厂
  animation.py       # 关键帧, 驱动, 程序化运动
  camera.py          # 绑定, 轨道/推拉, 景深, 构图检查
  lighting.py        # 主光/补光/轮廓光, HDRI, 自发光点缀
  simulation.py      # 粒子, 刚体, 布料 — 缓存设置
  render.py          # 引擎, 采样, 输出, 联系表, 编码
  shots/             # 每个镜头一个模块:shot_01.py, shot_02.py

不可协商的原则:

  • 幂等性。 重新运行构建仅更新你命名的集合/对象;它永远不会复制几何体或擦除无关的用户内容。
  • 命名。 Main_Logo, Cam_Orbit, Light_Key, Emitter_Particles。永远不要使用 Cube.003。
  • 配置化。 所有可调整的值都存在于 config.py 或数据类中,因此一次修订就是一行更改。
  • 断言式。 如果资产、相机、字体或输出目录缺失,则大声失败。
  • 范围限定。 清理仅删除你拥有名称的集合,前缀例如 MS_。

4. 场景构建

  • 优先使用数据 API(bpy.data.objects.new, bpy.data.meshes.new, collection.objects.link),而不是依赖选择、模式和区域上下文的 bpy.ops。
  • 当确实需要某个操作符时,请为该版本提供正确的上下文覆盖,并说明原因。
  • 通过节点和一个小型工厂函数构建材质;不要为每个对象复制粘贴20个节点的树。
  • 使用真实世界比例并设置场景单位系统;错误的比例会破坏景深、物理和光照。
  • 保持世界节点树明确(颜色、强度、HDRI),以便渲染结果可在另一台机器上复现。
  • 打包或相对化资产。//assets/... 路径加上一个打包文件夹,胜过使用某人下载目录的绝对路径。

5. 动画

有意识地选择机制:

需求使用
手动设定的位置/旋转/缩放/材质变化带有显式插值的关键帧
跟随另一个属性或表达式的属性驱动(简单且有文档说明的表达式)
重复/参数化运动(轨道、波浪、网格、螺旋)基于帧的数学计算,无状态求值
成千上万的实例、图案、散布几何节点
物理涌现的运动模拟(缓存,验证完整范围)
沿路径运动的相机曲线 + 跟随路径约束,或关键帧绑定

关键帧规范:

obj.location = (0, 0, 0)
obj.keyframe_insert("location", frame=1)
obj.location = (4, 0, 0)
obj.keyframe_insert("location", frame=48)

for fc in obj.animation_data.action.fcurves:
    for kp in fc.keyframe_points:
        kp.interpolation = 'BEZIER'
        kp.easing = 'EASE_IN_OUT'
        kp.handle_left_type = kp.handle_right_type = 'AUTO_CLAMPED'
  • 有目的地设置插值。默认贝塞尔适用于有机运动;使用 LINEAR 表示恒定速度和机械运动;使用 CONSTANT 表示步进/像素风格。
  • 切勿在循环周期上留下意外的缓动——它会在循环点产生卡顿。
  • 对于循环:使第1帧和第N+1帧相同,然后渲染 [1, N]。
  • 所有程序化内容必须是帧的纯函数:f(frame)。没有累积状态,没有未设置种子的 random。

6. 几何节点和实例化

当你需要规模、变化或非破坏性控制时,使用几何节点:

  • 散布/实例化(树木、碎片、星星、人群方块)。
  • 参数化阵列、网格、径向图案、伊斯兰几何镶嵌。
  • 动画位移、场和每个实例的旋转/缩放。
  • 将一个庞大的10,000个对象的Python循环转换为一个节点树。

通过名称使用 nodes.new(...) 和 links.new(...) 构建节点,而不是脆弱的索引。将用户可能要求的旋钮(数量、半径、种子、速度)暴露为修改器输入,以便修订无需代码更改。

7. 材质、灯光、相机

  • 材质: Principled BSDF 基础;明确的粗糙度/金属度;自发光用于点缀(保持克制——炫光无法挽救平淡的画面)。仅在需要时使用真正的透明,并在最终引擎中验证它。
  • 灯光: 主光 → 补光 → 轮廓光 → 环境光。形状和深度优先于装饰。检查曝光和高光剪切,而不仅仅是视口。
  • 相机: 根据主体选择焦距和构图。轨道、推拉、升降或固定——每个必须有理由。在极端帧处验证构图,而不仅仅是第1帧。优先使用平滑的贝塞尔手柄;添加微妙的静止而非硬停止。
  • 景深: 聚焦于故事点;切勿模糊小文本。

8. 引擎和渲染设置

引擎用途成本
EEVEE动态图形、风格化工作、快速迭代、预览低
Cycles照片级光照、反射、全局光照、玻璃、最终美图高
Workbench分镜、剪影、动画分镜非常低

不确定时测试两者;引擎速度取决于场景,而非宣传。GPU取决于构建、驱动和操作系统——始终保留CPU路径。

明确设置并记录:

scene.render.engine = 'BLENDER_EEVEE_NEXT'   # 4.2+;旧版本可能使用 'BLENDER_EEVEE'
scene.render.resolution_x, scene.render.resolution_y = 1920, 1080
scene.render.resolution_percentage = 100
scene.render.fps, scene.render.fps_base = 30, 1.0
scene.frame_start, scene.frame_end = 1, 300
scene.render.image_settings.file_format = 'PNG'
scene.render.image_settings.color_mode = 'RGBA'
scene.render.filepath = "//renders/shot_01/frame_"
  • 预览:25–50% 分辨率,低采样,EEVEE 或 Workbench。
  • 最终:全分辨率,根据外观选择引擎,如有帮助则降噪,正确的视图变换。
  • 颜色:一次确定视图变换(AgX/Filmic/Standard),应用于所有通道,并在下游的 Remotion/FFmpeg 中匹配。不匹配的变换是“合成看起来发白”的最常见原因。
  • 长时间渲染 → PNG(需要 HDR 时使用 EXR)序列,然后编码。直接视频输出仅用于快速审查。

9. 预览阶梯

  1. 在代表性帧处渲染一张静帧。
  2. 关键帧:第一帧、揭示、峰值、每次过渡、最后一帧。
  3. 包含最难运动段的低采样、低分辨率片段。
  4. 缩小尺寸、真实 FPS 的完整预览。
  5. 仅在 1–4 看起来正确后进行最终渲染。

通过联系表加上目标帧进行审查:

ffmpeg -i preview.mp4 -vf "fps=2,scale=320:-1,tile=4x4" -frames:v 1 previews/contact.jpg

检查闪烁、z-fighting、跳动、交叉、纹理漂移、相机剪裁、曝光变化和不可读的文本。

10. 文字、多语言和标志工作

  • 仅在确认文案和字体许可证后再将文本转换为网格;保留源文件中的可编辑文本对象。
  • 在制作动画前验证字形覆盖范围。对于波斯语/阿拉伯语,在渲染帧中检查连字、连接、从右到左顺序、变音符号和混合脚本标点——即使字符串正确,如果文本路径未正确整形,也可能渲染错误。
  • 对于品牌/标志工作,尽量获取矢量源文件;如果是位图,则有意识地描摹并在4K下检查边缘。
  • 对文字进行倒角/加粗,使其能够承受光照;避免纯黑对黑或纯白对白的边缘。

11. 性能和可靠性

  • 实例化,不要复制。在降低采样之前先降低细分级别。
  • 限制透明层和体积效果;它们通常是渲染时间的杀手。
  • 缓存模拟,并确认缓存位于项目内部或已记录在案。
  • 对脆弱的工作进行帧批次渲染;验证帧数并在编码前捕获缺失帧。
  • 监控 RAM/VRAM/磁盘。4K EXR 序列体积很大;在长时间渲染前检查可用空间。
  • 在使用较新 Blender 主版本打开/保存 .blend 之前先备份——较新文件可能无法在旧版本中打开。

12. 最小工作示例

# build.py — 使用以下命令运行:
# blender --background --factory-startup --python-exit-code 1 --python build.py
import bpy, bmesh, math, os

scene = bpy.context.scene
scene.frame_start, scene.frame_end = 1, 120
scene.render.fps = 30
scene.render.resolution_x, scene.render.resolution_y = 1920, 1080
scene.render.engine = 'BLENDER_EEVEE_NEXT'
scene.render.filepath = "//renders/frame_"

# 清理已拥有的集合
col = bpy.data.collections.get("MS_Main") or bpy.data.collections.new("MS_Main")
if col.name not in scene.collection.children:
    scene.collection.children.link(col)

def add_sphere(name, loc, radius, mat):
    """数据 API 球体:无操作符,无上下文依赖。"""
    mesh = bpy.data.meshes.new(name)
    bm = bmesh.new()
    bmesh.ops.create_uvsphere(bm, u_segments=32, v_segments=16, radius=radius)
    bm.to_mesh(mesh)
    bm.free()
    obj = bpy.data.objects.new(name, mesh)
    obj.location = loc
    col.objects.link(obj)
    obj.data.materials.append(mat)
    return obj

mat = bpy.data.materials.new("MS_Emission")
mat.use_nodes = True
bsdf = mat.node_tree.nodes["Principled BSDF"]
bsdf.inputs["Base Color"].default_value = (0.05, 0.6, 0.55, 1)
bsdf.inputs["Emission Color"].default_value = (0.1, 0.9, 0.8, 1)
bsdf.inputs["Emission Strength"].default_value = 3.0
bsdf.inputs["Roughness"].default_value = 0.3

core = add_sphere("MS_Core", (0, 0, 1), 0.8, mat)
core.keyframe_insert("scale", frame=1)
core.scale = (1.15, 1.15, 1.15)
core.keyframe_insert("scale", frame=40)
core.scale = (1.0, 1.0, 1.0)
core.keyframe_insert("scale", frame=90)

# 相机
cam_data = bpy.data.cameras.new("MS_Cam")
cam = bpy.data.objects.new("MS_Cam", cam_data)
col.objects.link(cam)
scene.camera = cam
cam.location = (6, -6, 3)
cam.rotation_euler = (math.radians(75), 0, math.radians(45))

# 保存
os.makedirs(bpy.path.abspath("//renders"), exist_ok=True)
bpy.ops.wm.save_as_mainfile(filepath=bpy.path.abspath("//scene.blend"))
print("BUILD OK", len(col.objects), "objects")

更多内容请参阅 references/BLENDER-RECIPES.md:轨道绑定、缓动、几何节点散布、粒子、文本、Alpha 通道、渲染农场脚本和编码命令。

13. Blender MCP(可选便利性)

后台模式下的脚本是生产路径:可重现、可差异比较、可调试、适合 CI。MCP 对于交互式场景检查和已在打开的会话中进行实时调整非常有用。它属于第三方集成,而非 Blender 组件。

如果用户需要:审查仓库和许可证,检查与已安装 Blender 的兼容性,理解它授予在 Blender 内执行任意 Python 的权限,将其绑定到回环接口,并且永远不要将其暴露给不受信任的网络。当前包名为 mcp-for-blender;请遵循仓库当前的设置说明,而非旧的 blender-mcp 片段。不要将其作为任何交付项目的依赖项。

14. 交付物

完成一项 Blender 工作后,你需要:

  1. output/final.mp4(或请求的格式),并使用 ffprobe 验证。
  2. blender/scripts/*.py — 构建源代码。
  3. scene.blend — 可编辑的项目,资产已打包或使用相对路径。
  4. renders/ 图像序列(或已记录的主文件)在有帮助时保留。
  5. README.md — 精确的 Blender 版本、安装、构建、预览、最终渲染和修订命令。
  6. 一份简短报告:工具、分辨率、FPS、时长、帧数、视觉上验证了哪些内容。

当用户要求一个他们可能需要更改的动画时,永远不要只交付 MP4。

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

aminghaseminia/motion-studio

End-to-end animation and motion-graphics production from a natural-language brief. Routes work to Blender (3D), Remotion (2D/typography/data), Manim (math/science), motion-design craft, and FFmpeg (encode/composite/validate), then builds, previews, inspects, revises, and delivers an editable project plus final MP4. Use for any request to "make an animation", "create a video", "animate this logo", "render a motion graphic", "vibe-code an animation", or produce a promo, explainer, title sequence, or social clip.

aminghaseminia/remotion-motion-graphics

Create 2D motion graphics as code with Remotion and React — kinetic typography, logo reveals, explainers, animated charts, UI demos, social clips, subtitles, and data-driven or batch-rendered video. Use when the deliverable is primarily layout, text, and 2D graphics rather than real 3D; when a video must be generated from data or a template; or when a Blender 3D pass needs titles, captions, and transitions composited on top. Covers project setup, deterministic frame-based animation, easing, typography, audio, rendering, and licensing.

aminghaseminia/video-composition

Assemble, mix, normalize, and validate finished video from Blender, Remotion, Manim, screen capture, and audio sources using FFmpeg and FFprobe — concatenation, overlays, alpha compositing, subtitle burn-in, loudness, fades, speed ramps, GIF/thumbnail export, and platform-specific encodes. Use when combining scenes, fixing mismatched resolutions or frame rates, adding music/voice-over, burning captions, converting formats, or verifying that a rendered file is actually correct.

相关技能