APIMODELSAPIMODELS

用 Claude Code 写 Blender Python

TL;DR Claude Code 配 Blender,最好的方式是走命令行:blender -b -P scene.py 不开窗口直接运行 Python 脚本,于是 Claude 可以自己写 bpy 脚本、先渲染几张小图、打开 PNG 看哪里不对、改好,再用 Blender 自带的 FFmpeg 输出完整视频。几何体、材质、关键帧、镜头、灯光全部用代码生成。在我们的 Apple M4 上用 Blender 5.3,下面这个测试脚本渲染三张预览帧(含启动)约 26 秒,72 帧 1280×720 的 MP4 用 EEVEE 渲了 77 秒。最难的场景交给 Claude Fable 5.2,日常迭代用 Opus 5.5 或 Sonnet 5.5。

Claude Fable 5.2 在 2026 年 11 月 9 日发布后,传播最广的作品里有不少是在 Blender 里做的,而且没人碰过 Blender 的界面。记录最完整的是一只骑自行车的写实鹈鹕:作者公开的会话记录显示,Fable 5.2 在 Claude Code 里从零写 Blender 脚本,用了约 2 小时 44 分钟、约 110 万输出 token,再用 Cycles 在 RTX 5080 上渲染 444 帧,约 56 分钟。还有创作者用 Fable 5.2 配 Blender 做了一部 90 秒、逐帧描线的日式动画短片,以及一条缠绕帆船的海蛇。

这一页把这条路子整理成可以复用的步骤。下面的脚本、命令和耗时都来自我们在 Blender 5.3 上的实际运行,验证的是工具链,不是模型。我们运营 apimodels.app,所以配置那一步写的是我们的地址,但这里的一切换成任何兼容 Anthropic 的地址都能用。

装好 Blender,配好 Claude Code

从 blender.org 安装 Blender,macOS 上也可以用 brew install --cask blender。Claude 需要知道可执行文件在哪:macOS 是 /Applications/Blender.app/Contents/MacOS/Blender,大多数 Linux 是 blender,Windows 是安装目录下的 blender.exe。把路径写进项目说明或下面的技能文件里,每次会话都能找到。

然后设好 ANTHROPIC_BASE_URL=https://api.apimodels.app、ANTHROPIC_AUTH_TOKEN 填你的 key、ANTHROPIC_MODEL 填想用的模型。Blender 会话里同一个长脚本要反复读很多次,所以第一版用最强的模型写,之后的小改动用 /model 切到更省钱的模型更划算。

模型名每百万 token 价格(输入 / 输出)适合
claude-fable-5-2$4.80 / $24写实场景、角色,需要很多轮「渲染—修改」的活
claude-opus-5-5$2.40 / $12大多数场景和修改
claude-sonnet-5-5$1.20 / $6小改动:镜头、灯光、节奏、材质

为什么走命令行,而不是开 Blender 窗口

blender -b 让 Blender 以后台模式运行、不开窗口,-P 执行一个 Python 脚本,-- 之后的参数会通过 sys.argv 传给脚本。这对 Claude Code 来说已经够用:它写 scene.py,跑一条命令,拿到可以打开检查的 PNG 或 MP4。整个过程可复现,脚本放在你的仓库里,也不依赖界面当时开着什么。

想让 Claude 操作一个你正看着的 Blender 窗口,可以用 Blender 的 MCP 服务器,有创作者就是这样做出能直接进游戏的生物模型。但只要最终要的是渲染出来的视频,命令行更好配置,也更容易重跑。

一个好的场景脚本长什么样

「调用示例」里的脚本就是行得通的结构:用 read_factory_settings(use_empty=True) 从空场景开始,默认文件里的东西一样都不带进来;用几个小函数生成几何体和材质;每个关键帧都由帧号算出来,动画是确定的;最后加镜头、灯光和世界背景;再留两种模式,快速预览和正式渲染,用 -- 后面的参数切换。

要求 Claude 所有东西都用代码生成,除非你自己提供,否则不下载模型、贴图或 HDRI。这样成品可以放心分发,公开的那些 Fable 5.2 Blender 作品也都是这样做的。场景里不止一个物体时,先让它写可复用的生成函数,再用这些函数拼场景。

先渲小图,看过、改过,再正式渲染

预览模式按最终尺寸的四分之一渲染三个关键帧,在我们的电脑上连 Blender 启动一共约 26 秒。Claude Code 可以打开这些 PNG,看出哪里不对。我们自己第一次预览就说明了这一步为什么重要:第 18 帧球弹得太高,顶出了画面。调低弹跳、挪一下镜头,只改一次、再预览一次就好了,不用白白渲一整遍。

要求 Claude 在正式长渲染之前,先用预览量出每帧耗时,并告诉你整段要渲多久。上面那只鹈鹕用 Cycles 在台式机显卡上渲 444 帧花了约 56 分钟,渲完才发现问题,就要再搭进一个小时。

Blender 5 里怎么直接出视频

Blender 可以直接写出 MP4。在 Blender 5.x 里,先把输出的 media_type 设成 VIDEO,再把 file_format 设成 FFMPEG,然后选 MPEG4 容器和 H264 编码;我们脚本的正式模式在 Apple M4 上用 EEVEE 把 72 帧 1280×720 渲成了 3 秒的 H.264 视频,用时 77 秒。也可以先渲 PNG 序列再用 ffmpeg 合成,好处是改编码参数不用重渲。

Python API 每个版本都会变,这也是 Claude 凭记忆写的脚本最常见的出错原因。在 Blender 5.3 里,EEVEE 引擎的标识符是 BLENDER_EEVEE;Material.use_nodes 和 World.use_nodes 已经弃用,因为节点树默认就有。让 Claude 在会话开头先打印 bpy.app.version 和可用的引擎名,不要靠记忆。

把规则存成 Claude Code 技能

把下面的 SKILL.md 放进 ~/.claude/skills/blender-scene/(所有项目生效),或者某个仓库的 .claude/skills/blender-scene/(只对这个仓库生效),再填上你的 Blender 路径。请求和描述对得上时 Claude Code 会自动加载它,所以一句「用 Blender 做一个 10 秒的黄昏灯塔镜头」,命令行、全部代码生成、先预览这些规则就都带上了。

一次长的 Blender 任务花多少钱

大头是输出 token。那只鹈鹕的会话在 Fable 5.2 上用了约 110 万输出 token,按 apimodels.app 每百万 $24 算,光输出约 $26.40,按 Anthropic 官方价是 $44,还没算输入和缓存读。每一轮都会重读越来越长的脚本,缓存读每百万 $0.12,这部分花不了多少。像我们测试这样的简单场景只要其中一小部分;修改阶段换成 Opus 5.5,单价直接减半。每次请求的准确扣费都能在控制台的调用记录里看到。

这条路的短板

角色动画是短板:代码搭的骨架动起来往往很僵,有创作者反映,让 Claude 看过第一次失败的效果、重做一遍骨架之后,动作好了很多。逼真的人物交给视频模型,不适合用 Blender 脚本做。Cycles 用 CPU 渲染很慢,长的写实镜头需要显卡。如果必须用某个有版权的特定素材,把文件给它、让它加载,不要让它去仿造。

调用示例

scene.py · empty scene to MP4, all in code (tested on Blender 5.3)

# scene.py: build a small animated scene entirely in code and render it.
# usage:
#   blender -b -P scene.py -- --preview      # 3 key frames at 25% size, as PNG
#   blender -b -P scene.py -- --final        # every frame at full size, as MP4
import sys, math, os
import bpy

args = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
PREVIEW = "--preview" in args
OUT = os.path.abspath(os.path.join(os.path.dirname(__file__), "out"))

bpy.ops.wm.read_factory_settings(use_empty=True)  # start from an empty scene
scene = bpy.context.scene
scene.frame_start, scene.frame_end = 1, 72          # 3 seconds at 24 fps
scene.render.fps = 24

def material(name, rgb, rough=0.5, metal=0.0):
    m = bpy.data.materials.new(name)
    p = m.node_tree.nodes["Principled BSDF"]
    p.inputs["Base Color"].default_value = (*rgb, 1)
    p.inputs["Roughness"].default_value = rough
    p.inputs["Metallic"].default_value = metal
    return m

# ground and a bouncing ball, all generated in code
bpy.ops.mesh.primitive_plane_add(size=20)
bpy.context.object.data.materials.append(material("Ground", (0.08, 0.09, 0.12), rough=0.9))
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.6, segments=64, ring_count=32)
ball = bpy.context.object
bpy.ops.object.shade_smooth()
ball.data.materials.append(material("Ball", (0.95, 0.45, 0.15), rough=0.25))

# keyframes: three bounces, squashed on contact
for f in range(scene.frame_start, scene.frame_end + 1):
    t = (f - 1) / 24
    phase = (t % 1.0)
    height = 4 * phase * (1 - phase) * 2.0          # parabola per bounce
    ball.location = (t * 1.2 - 1.8, 0, 0.6 + height)
    squash = 1 - 0.25 * max(0.0, 1 - height / 0.4)
    ball.scale = (1 / math.sqrt(squash), 1 / math.sqrt(squash), squash)
    ball.keyframe_insert("location", frame=f)
    ball.keyframe_insert("scale", frame=f)

# light, camera, world
bpy.ops.object.light_add(type="SUN", location=(4, -4, 8))
bpy.context.object.data.energy = 3.0
bpy.context.object.rotation_euler = (math.radians(50), 0, math.radians(35))
bpy.ops.object.camera_add(location=(0, -10, 2.4), rotation=(math.radians(84), 0, 0))
scene.camera = bpy.context.object
scene.world = bpy.data.worlds.new("World")
scene.world.node_tree.nodes["Background"].inputs["Color"].default_value = (0.02, 0.025, 0.035, 1)

# render settings
scene.render.engine = "BLENDER_EEVEE"
scene.render.resolution_x, scene.render.resolution_y = 1280, 720
scene.render.resolution_percentage = 25 if PREVIEW else 100

if PREVIEW:
    scene.render.image_settings.file_format = "PNG"
    for f in (1, 18, 36):
        scene.frame_set(f)
        scene.render.filepath = os.path.join(OUT, f"preview_{f:03d}.png")
        bpy.ops.render.render(write_still=True)
else:
    scene.render.image_settings.media_type = "VIDEO"
    scene.render.image_settings.file_format = "FFMPEG"
    scene.render.ffmpeg.format = "MPEG4"
    scene.render.ffmpeg.codec = "H264"
    scene.render.filepath = os.path.join(OUT, "ball_")
    bpy.ops.render.render(animation=True)

Terminal · preview, then final (tested on Blender 5.3, Apple M4)

# macOS path; on Linux use "blender", on Windows the full path to blender.exe
BLENDER=/Applications/Blender.app/Contents/MacOS/Blender

$BLENDER -b -P scene.py -- --preview   # 3 frames at 25% size -> out/preview_*.png  (~26 s)
$BLENDER -b -P scene.py -- --final     # 72 frames at 1280x720 -> out/ball_0001-0072.mp4  (77 s, EEVEE)

~/.claude/skills/blender-scene/SKILL.md (ours)

---
name: blender-scene
description: Build, preview and render Blender scenes and animations with Python from the command line. Use when the user asks for a 3D scene, model, animation or rendered video made in Blender.
---

# Blender scenes from the command line

Blender: /Applications/Blender.app/Contents/MacOS/Blender   (edit for your machine)

1. Never open the Blender window. Run: BLENDER -b -P scene.py -- <args>.
2. At the start of a session, print bpy.app.version and the available render
   engines; do not rely on memory for API names.
3. Start from bpy.ops.wm.read_factory_settings(use_empty=True). Generate all
   geometry, materials, keyframes, camera and lights in code. No downloaded
   models, textures or HDRIs unless the user supplies them.
4. Compute every keyframe from the frame number so the animation is
   deterministic. Write reusable generator functions before assembling.
5. Keep two modes: --preview renders 3-6 key frames at 25% size as PNG;
   --final renders the whole animation.
6. After every change, run --preview, open the PNGs, list what looks wrong
   (out of frame, clipping, flat light, stiff motion), fix, and repeat.
7. Before --final, measure seconds per frame on the preview and tell the user
   how long the full render will take.
8. Video in Blender 5.x: image_settings.media_type = "VIDEO", then
   file_format = "FFMPEG", ffmpeg.format = "MPEG4", ffmpeg.codec = "H264".

Prompt template · Blender shot (ours)

Make a [length]-second Blender shot at [1280x720, 24fps]: [subject],
[camera move], [light and time of day], [mood].
Follow the blender-scene skill: command line only, everything generated in
code, deterministic keyframes. Show me the --preview frames and what you
fixed before you run --final, and tell me the expected render time first.

cURL

curl https://api.apimodels.app/v1/messages \
  -H "x-api-key: $APIMODELS_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-fable-5-2",
    "max_tokens": 64000,
    "messages": [{"role": "user", "content": "Write a Blender 5.3 Python script, run with blender -b -P, that builds a lighthouse at dusk entirely in code and renders 3 preview frames at 25% size."}]
  }'

常见问题

Claude Code 能用 Blender 吗?

能。Claude Code 写一个 Python 脚本,用 blender -b -P scene.py 运行,不需要开窗口;然后打开渲染出来的 PNG 或 MP4 检查效果。想让它操作你正看着的 Blender 窗口,也可以用 Blender 的 MCP 服务器。

怎么用命令行渲染 Blender 动画?

运行 blender -b -P scene.py,在脚本里设好帧范围、分辨率和输出,再调用 bpy.ops.render.render(animation=True)。Blender 5.x 里要直接出 MP4,先把输出的 media_type 设成 VIDEO,再选 FFMPEG。我们 72 帧 1280×720 的测试用 EEVEE 在 Apple M4 上渲了 77 秒。

Claude 写的 Blender 脚本为什么报属性错误?

最常见的原因是 Blender API 版本之间有变化:引擎标识符、输出设置、节点选项每个版本都可能改。先让 Claude 打印 bpy.app.version 和可用的引擎名;在 Blender 5.x 上别再写 Material.use_nodes 和 World.use_nodes,它们已经弃用,节点树默认就有。

用 Blender 选哪个 Claude 模型最好?

最难的公开 Blender 作品是 Claude Fable 5.2 做的,比如在 Claude Code 里花了将近三小时做出来的写实骑车鹈鹕。简单场景和修改阶段,用 apimodels.app 上每百万 token $2.40 / $12 的 Opus 5.5,价格是 Fable 5.2 的一半;小改动用 $1.20 / $6 的 Sonnet 5.5。

用 Claude 做一个 Blender 动画要多少钱?

一次长的写实任务可能用掉约 100 万输出 token:公开的鹈鹕会话在 Fable 5.2 上用了约 110 万,按 apimodels.app 的价格光输出约 $26.40,还没算输入和缓存读。简单场景只要其中一小部分,修改阶段换成 Opus 5.5 单价减半。

相关阅读

收录于
APIMODELS on Product HuntAPIMODELS featured on ToolifyAPIMODELS featured on There's An AI For That