最近在折腾 AI 辅助 3D 建模时,发现一条很有意思的技术路径:用 Codex 作为智能体调度器,接入 DeepSeek 大模型,再通过 skill 技能文件约束 Codex 的行为,让它自动调用 Blender 的 Python API 完成建模。这套流程不仅能处理重复性的建模操作,还能根据自然语言描述直接生成完整的 3D 场景。
本文就以“打造自己的天宫仙境”为例,完整拆解 DeepSeek、Codex、Blender 三者联动的方法,包括环境配置、skill 文件编写、Blender Python 建模入门、完整可运行脚本和常见报错排查。无论你是想入门 AI 辅助建模,还是已经有 Blender 基础想接入 Codex,这篇文章都能给你一套闭环实操方案。
1. 背景与核心概念
1.1 为什么需要 Codex 控制 Blender 建模
Blender 是一款功能强大的开源 3D 建模软件,它的优势之一在于内置了完整的 Python API(模块名为bpy),几乎所有界面操作都能通过脚本完成。这意味着,只要我们有能力生成正确的 Python 脚本,就能实现“自动建模”。
但问题在于:Blender 的 Python API 非常丰富,从物体创建、修改器设置、材质分配到渲染输出,涉及的参数成百上千。手动编写这些脚本对新手来说门槛很高,即使是熟练开发者,写一个复杂的场景脚本也需要不少时间。
这时候,AI 编码智能体的价值就体现出来了。Codex 是 OpenAI 推出的命令行编码智能体,它可以在终端中理解自然语言任务,自动编写代码、执行命令、调试错误。更进一步,Codex 支持通过 skill 机制注入特定的任务规则,让它在特定场景下按照你的约束工作。
换句话说,我们可以对 Codex 说:
帮我在 Blender 里生成一个天宫仙境场景:云海平面、悬浮山体、中式宫殿主体、灯光和相机。Codex 会结合 skill 中定义的建模规范,生成一段可执行的 Blender Python 脚本,然后交给 Blender 后台运行,最终输出渲染图。这就是整个流程的核心逻辑。
1.2 DeepSeek 在流程中扮演什么角色
DeepSeek 是深度求索推出的大语言模型,它的 API 兼容 OpenAI 格式,可以作为一个模型后端接入 Codex。也就是说,Codex 负责任务拆解、工具调用和代码执行,而 DeepSeek 负责理解自然语言指令、生成代码片段、判断报错信息。
这种组合的吸引力在于:
- DeepSeek API 的调用成本相对较低,适合高频实验。
- Codex 的开源 CLI 支持自定义模型提供商,不需要绑定特定云服务。
- 两者组合后,相当于拥有一个“免费的智能建模助手”,你只需要按 API 用量付费。
1.3 skill 机制是什么
skill(技能)是 AI 编程智能体中的一种配置机制,核心思想是:把某一类任务的执行规则写成独立文件,在任务启动时注入给模型,让模型的行为更可控。
在 Codex 项目中,通常会在项目根目录下创建类似.codex/skills/的目录,每个技能对应一个SKILL.md文件。文件里写清楚:这个技能解决什么问题、代码要遵循什么规范、调用外部工具时要注意什么、输出格式是什么。
当用户请求触发了对应技能时,Codex 会优先按照 skill 里的规则生成和处理内容。这种思路和我们平时写提示词很相似,但更结构化、更适合工程化复用。
整个链路可以用下面的 ASCII 图表示:
用户输入自然语言 ↓ Codex CLI(读取 skill 规则) ↓ DeepSeek API(推理 + 生成 Python 代码) ↓ Codex 执行命令:blender --background --python generate_scene.py ↓ Blender Python API(bpy)构建 3D 场景 ↓ 渲染输出 PNG / 保存 .blend 文件2. 环境准备与版本说明
2.1 环境清单
在开始之前,我们需要准备好以下工具。版本号请以你实际安装时官方发布的最新稳定版为准,这里给出的是示例参考。
| 组件 | 说明 | 版本建议 |
|---|---|---|
| Blender | 开源 3D 建模软件 | 4.x 及以上 |
| Node.js | Codex CLI 的运行时依赖 | 18 或更高 |
| Codex CLI | OpenAI 推出的命令行编码智能体 | 最新稳定版 |
| DeepSeek API Key | 用于调用 DeepSeek 大模型 | 在 DeepSeek 开放平台申请 |
| Python | Blender 内置 Python,也建议系统安装 | 3.10 或更高 |
| 操作系统 | Windows / macOS / Linux 均可 | 以 Blender 官方支持为准 |
2.2 安装 Blender
去 Blender 官网下载对应操作系统的安装包。安装完成后,打开终端验证:
blender --version如果能输出版本信息,说明安装成功。在 Windows 上如果提示找不到命令,需要把 Blender 的安装目录添加到系统环境变量的 PATH 中,或者直接使用完整路径调用。
2.3 安装 Node.js 和 Codex CLI
Codex CLI 官方推荐通过 npm 全局安装:
npm install -g @openai/codex安装完成后验证:
codex --version如果这一步出现了类似unable to locate the codex cli binary的报错,说明 VS Code 插件或者 IDE 集成层找不到 codex 的可执行文件。解决办法是在 IDE 设置里手动配置 codex 的路径,或者确认全局 npm bin 目录已经加入 PATH。
2.4 准备 DeepSeek API Key
登录 DeepSeek 开放平台,创建一个 API Key。这个 Key 是敏感凭证,不要提交到 Git 仓库,建议通过环境变量注入。
3. Codex 接入 DeepSeek
3.1 配置原理
Codex CLI 支持通过config.toml配置文件自定义模型提供商。由于 DeepSeek 的 API 兼容 OpenAI 的接口格式,我们可以把 DeepSeek 作为一个 OpenAI 兼容端点接入 Codex。
Codex 的配置文件通常位于:
~/.codex/config.toml3.2 编写配置文件
在配置文件中添加如下内容:
# 文件路径:~/.codex/config.toml model = "deepseek-chat" model_provider = "deepseek" [model_providers.deepseek] name = "DeepSeek" base_url = "https://api.deepseek.com/v1" env_key = "DEEPSEEK_API_KEY"字段说明:
model:指定默认使用的模型名称。DeepSeek 的通用对话模型是deepseek-chat,也可以根据你的账户权限选择其他模型。model_provider:指定使用下方定义的哪个提供商。[model_providers.deepseek]:定义一个名为deepseek的模型提供商。base_url:DeepSeek API 的兼容地址。env_key:指定从哪个环境变量读取 API Key。
然后导出环境变量:
export DEEPSEEK_API_KEY=sk-你的key3.3 验证 Codex 是否成功接入 DeepSeek
运行一个简单任务:
codex exec "用 python 打印 1 到 10 的平方"如果配置正确,Codex 会调用 DeepSeek 的接口生成 Python 代码并执行。
需要注意的是,Codex 的配置格式在不同版本上可能存在差异,请以官方文档为准。上面这种方式适用于支持model_providers配置的版本,如果你的版本较旧,也可以直接设置 OpenAI 兼容环境变量:
export OPENAI_BASE_URL=https://api.deepseek.com/v1 export OPENAI_API_KEY=sk-你的key但这种方式会覆盖其他依赖 OpenAI 环境变量的工具,建议还是使用独立的config.toml配置。
4. skill 机制与核心配置
4.1 skill 文件放在哪里
以 Codex 项目为例,可以在项目根目录下创建如下结构:
codex-blender-project/ ├── .codex/ │ └── skills/ │ └── blender-modeling/ │ └── SKILL.md ├── scripts/ │ └── generate_scene.py ├── output/ │ └── render.png └── requests/ └── prompt.txtSKILL.md是技能定义文件,它会被 Codex 在任务启动时读取,作为系统上下文注入。
4.2 SKILL.md 文件应该写什么
一个完整的建模 skill 文件至少应该包含以下内容:
- 技能名称和触发条件:什么场景下使用该技能。
- 执行流程:从解析需求到生成脚本、运行脚本、反馈结果的步骤。
- 代码规范:Blender Python 脚本的命名规则、结构要求。
- 注意事项:比如不要使用系统 Python 运行 bpy、注意坐标轴、单位等。
- 输出要求:脚本保存路径、渲染结果保存路径。
下面是一个 Blender 建模技能文件的示例:
# Blender 建模技能 ## 触发条件 当用户请求使用 Blender 创建 3D 场景、生成 .blend 文件或渲染图片时,使用本技能。 ## 执行流程 1. 分析用户需求,拆解场景元素列表。 2. 编写完整的 Blender Python 脚本,保存到 scripts/ 目录。 3. 使用 Blender 后台模式执行脚本: blender --background --python scripts/xxx.py 4. 检查执行结果和渲染输出,如有报错则修复后重试。 ## 代码规范 - 所有脚本必须使用 bpy 模块。 - 脚本开头先清空默认场景。 - 材质命名使用 material_ 前缀。 - 物体命名使用 obj_ 前缀。 - 渲染参数统一使用 EEVEE 引擎,分辨率设置为 1920x1080。 - 输出图片保存到 output/ 目录。 ## 注意事项 - 不要使用系统 Python 运行 bpy,必须通过 blender 可执行文件运行脚本。 - 添加物体时注意坐标和缩放,保证场景比例协调。 - 渲染完成后给出结果文件的绝对路径。这份文件的核心作用就是:告诉 Codex 在生成 Blender 脚本时遵守哪些规则。你可以在实际项目中不断迭代这个文件,让 Codex 的输出越来越稳定。
4.3 Codex 如何读取 skill 文件
Codex 在启动时会自动扫描项目目录中的AGENTS.md或配置的 skill 目录。不同版本的实现方式可能不同,但总体思路一致:把 skill 文件的文本内容作为上下文的一部分发送给模型。
因此,写 skill 文件时要注意:
- 语言要明确,尽量用“必须”“禁止”“统一使用”这类强约束词。
- 内容不要过长,模型上下文有限,重点写清楚规则即可。
- 可以按技能拆分成多个文件,避免一个文件过于臃肿。
5. Blender Python 建模基础
在让 Codex 生成复杂场景之前,我们先来梳理 Blender Python API 的核心用法。理解这些基础,你才能判断 Codex 生成的代码是否合理,也才能在出错时快速定位问题。
5.1 清空默认场景
新建的 Blender 场景默认包含一个立方体、一个灯光和一个相机。为了从零开始建模,我们需要先清空场景:
import bpy # 清除所有物体 bpy.ops.object.select_all(action='SELECT') bpy.ops.object.delete(use_global=False)5.2 添加基本几何体
Blender 中创建物体的入口是bpy.ops.mesh.primitive_*_add系列操作:
# 添加一个平面 bpy.ops.mesh.primitive_plane_add(size=10, location=(0, 0, 0)) # 添加一个立方体 bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 1)) # 添加一个圆柱体 bpy.ops.mesh.primitive_cylinder_add(radius=0.5, depth=2, location=(0, 0, 1)) # 添加一个球体(用于模拟悬浮山) bpy.ops.mesh.primitive_uv_sphere_add(radius=1, location=(0, 0, 2))在添加物体时,建议同时指定尺寸和位置,避免之后手动缩放。
5.3 设置材质
创建材质并赋予物体的基本流程如下:
import bpy # 创建新材质 material = bpy.data.materials.new(name="material_cloud") material.use_nodes = True # 修改基础颜色 material.node_tree.nodes["Principled BSDF"].inputs[0].default_value = (0.9, 0.9, 1.0, 1.0) # 把材质赋给场景中名为 "obj_cloud_plane" 的物体 obj = bpy.data.objects["obj_cloud_plane"] if obj.data.materials: obj.data.materials[0] = material else: obj.data.materials.append(material)Principled BSDF是 Blender 的通用 PBR 材质节点,第一个输入是 Base Color(基础颜色)。
5.4 添加修改器
修改器可以让我们用程序化方式改变模型形状。例如给平面添加一个噪波置换修改器,模拟云海的起伏:
import bpy # 选中目标物体 bpy.context.view_layer.objects.active = bpy.data.objects["obj_cloud_plane"] obj = bpy.data.objects["obj_cloud_plane"] obj.select_set(True) # 添加置换修改器 mod = obj.modifiers.new(name="displace_cloud", type='DISPLACE') mod.strength = 0.3 # 创建纹理并设置到修改器 tex = bpy.data.textures.new(name="cloud_noise", type='CLOUDS') mod.texture = tex这里的CLOUDS纹理是 Blender 内置程序化纹理,适合做云朵、烟雾类的效果。
5.5 设置相机和灯光
没有相机和灯光的场景,渲染出来是黑屏:
import bpy # 添加相机 camera_data = bpy.data.cameras.new("camera_main") camera_obj = bpy.data.objects.new("camera_main", camera_data) bpy.context.collection.objects.link(camera_obj) camera_obj.location = (8, -8, 5) camera_obj.rotation_euler = (1.1, 0, 0.8) # 设置场景相机 bpy.context.scene.camera = camera_obj5.6 渲染输出
配置渲染引擎、分辨率,并输出图片:
import bpy bpy.context.scene.render.engine = 'BLENDER_EEVEE_NEXT' bpy.context.scene.render.resolution_x = 1920 bpy.context.scene.render.resolution_y = 1080 bpy.context.scene.render.image_settings.file_format = 'PNG' bpy.context.scene.render.filepath = "//output/render.png" bpy.ops.render.render(write_still=True)运行渲染时,如果使用--background模式,记得在脚本中显式指定输出路径。
5.7 命令行执行脚本
Blender 支持后台模式执行 Python 脚本:
blender --background --python scripts/generate_scene.py这种模式不会弹出 Blender 窗口,适合自动化任务。脚本中可以正常操作 bpy,但无法打开界面。
6. 完整实战:让 Codex 自动生成天宫仙境
6.1 需求描述
现在进入核心环节。我们要实现的需求是:
在 Blender 中生成一个天宫仙境场景,包含:云海平面、悬浮山体、中式风格宫殿主体(底座、柱子、屋顶、台阶)、灯光和相机,最终渲染一张 1920x1080 的图片。
整个流程分成三步:
- 编写一个专门的 skill 文件,告诉 Codex 如何生成 Blender 脚本。
- 向 Codex 发送自然语言任务。
- Codex 自动生成脚本并调用 Blender 执行。
6.2 编写天宫建模 skill 文件
在项目目录中创建.codex/skills/tiangong-modeling/SKILL.md:
# 天宫仙境建模技能 ## 触发条件 当用户要求生成天宫、仙境、仙侠场景、云雾宫殿等 3D 场景时,使用本技能。 ## 场景元素规范 - 云海平面:使用 CLOUDS 纹理置换,材质为半透明浅蓝色。 - 悬浮山体:使用圆锥体或球体组合,材质为深绿色到青色的渐变。 - 宫殿主体: - 底座:长方体,深灰色石材材质。 - 柱子:圆柱体,红色材质。 - 屋顶:使用棱锥或缩放后的立方体模拟中式飞檐,金色材质。 - 台阶:逐级升高的长方体贴合在底座前方。 - 灯光:至少一盏主光源,一盏补光。 - 相机:选择一个能够看到宫殿和云海的俯视角度。 ## 代码规范 - 脚本开头使用 `import bpy`。 - 清空场景后开始建模。 - 所有物体必须指定名称,例如 `obj_palace_base`。 - 脚本文件保存到 scripts/ 目录,文件名使用 generate_tiangong.py。 - 渲染分辨率 1920x1080,格式 PNG,输出到 output/tiangong.png。 ## 执行方式 - 生成脚本后,使用以下命令执行: blender --background --python scripts/generate_tiangong.py - 如果运行报错,阅读报错信息并修复后重新执行。将以上内容保存后,Codex 就能在天宫场景任务中读取这套约束。
6.3 向 Codex 发起建模请求
在项目根目录运行:
codex exec "按照天宫仙境建模技能,生成一个天宫场景,并渲染输出图像"Codex 会先读取 skill 文件,然后调用 DeepSeek 模型生成 Python 脚本,最后在终端中执行 Blender 命令。整个过程你只需要等待。
6.4 一份可直接运行的天宫场景脚本
为了让不熟悉 Blender Python 的读者也能跑通流程,这里给出一份完整可运行的参考脚本。你可以把它保存为scripts/generate_tiangong.py,也可以作为 Codex 输出的参考模板。
# 文件路径:scripts/generate_tiangong.py import bpy import math # ---------- 清空场景 ---------- bpy.ops.object.select_all(action='SELECT') bpy.ops.object.delete(use_global=False) # ---------- 共享函数 ---------- def create_material(name, color, metallic=0.0, roughness=0.5): mat = bpy.data.materials.new(name=name) mat.use_nodes = True bsdf = mat.node_tree.nodes["Principled BSDF"] bsdf.inputs["Base Color"].default_value = color bsdf.inputs["Metallic"].default_value = metallic bsdf.inputs["Roughness"].default_value = roughness return mat def assign_material(obj_name, material): obj = bpy.data.objects[obj_name] if obj.data.materials: obj.data.materials[0] = material else: obj.data.materials.append(material) # ---------- 云海平面 ---------- bpy.ops.mesh.primitive_plane_add(size=40, location=(0, 0, 0)) bpy.context.object.name = "obj_cloud_plane" bpy.ops.object.modifier_add(type='DISPLACE') mod = bpy.context.object.modifiers[-1] mod.name = "displace_cloud" mod.strength = 0.4 tex = bpy.data.textures.new(name="cloud_noise", type='CLOUDS') mod.texture = tex cloud_mat = create_material("material_cloud", (0.85, 0.9, 1.0, 1.0), roughness=1.0) assign_material("obj_cloud_plane", cloud_mat) # 将云海平面细分,让置换更平滑 bpy.ops.object.select_all(action='DESELECT') bpy.context.view_layer.objects.active = bpy.data.objects["obj_cloud_plane"] bpy.data.objects["obj_cloud_plane"].select_set(True) bpy.ops.object.modifier_add(type='SUBSURF') bpy.context.object.modifiers[-1].levels = 3 # ---------- 悬浮山体 ---------- def create_floating_mountain(name, location, scale): bpy.ops.mesh.primitive_cone_add(vertices=8, radius1=1.2, depth=2, location=location) cone = bpy.context.object cone.name = name cone.scale = scale bpy.ops.mesh.primitive_uv_sphere_add(radius=1.5, location=(location[0], location[1], location[2] + 0.8)) sphere = bpy.context.object sphere.name = name + "_top" sphere.scale = (scale[0] * 0.8, scale[1] * 0.8, scale[2] * 0.6) mountain_mat = create_material(name + "_mat", (0.2, 0.5, 0.4, 1.0), roughness=0.8) assign_material(cone.name, mountain_mat) assign_material(sphere.name, mountain_mat) create_floating_mountain("obj_mountain_left", (-6, -3, 1.2), (1.2, 1.2, 1.0)) create_floating_mountain("obj_mountain_right", (7, 2, 1.0), (1.0, 1.4, 1.2)) create_floating_mountain("obj_mountain_back", (2, -8, 0.8), (1.5, 1.2, 0.8)) # ---------- 宫殿主体 ---------- # 底座 bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0.4)) base = bpy.context.object base.name = "obj_palace_base" base.scale = (6, 4, 0.8) base_mat = create_material("material_base", (0.3, 0.3, 0.32, 1.0), metallic=0.1, roughness=0.6) assign_material("obj_palace_base", base_mat) # 柱子 def create_pillar(name, location): bpy.ops.mesh.primitive_cylinder_add(radius=0.18, depth=2.2, location=location) pillar = bpy.context.object pillar.name = name pillar_mat = create_material(name + "_mat", (0.8, 0.2, 0.2, 1.0), metallic=0.2, roughness=0.4) assign_material(name, pillar_mat) positions = [ (-2.5, -1.5, 1.9), (-2.5, 1.5, 1.9), (2.5, -1.5, 1.9), (2.5, 1.5, 1.9), (-2.5, -1.5, 0.0), (-2.5, 1.5, 0.0), (2.5, -1.5, 0.0), (2.5, 1.5, 0.0), ] for i, pos in enumerate(positions): create_pillar("obj_pillar_{}".format(i), (pos[0], pos[1], pos[2])) # 主屋顶(简化版中式飞檐) bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 3.2)) roof = bpy.context.object roof.name = "obj_roof_main" roof.scale = (5.5, 3.8, 0.2) roof_mat = create_material("material_roof", (1.0, 0.8, 0.2, 1.0), metallic=0.6, roughness=0.3) assign_material("obj_roof_main", roof_mat) # 屋顶尖顶装饰 bpy.ops.mesh.primitive_cone_add(vertices=6, radius1=0.4, depth=1.0, location=(0, 0, 3.9)) finial = bpy.context.object finial.name = "obj_roof_finial" finial_mat = create_material("material_finial", (0.9, 0.7, 0.2, 1.0), metallic=0.8, roughness=0.2) assign_material("obj_roof_finial", finial_mat) # 台阶 for i in range(3): bpy.ops.mesh.primitive_cube_add(size=1, location=(0, -2.6, 0.25 + i * 0.5)) step = bpy.context.object step.name = "obj_step_{}".format(i) step.scale = (3.5 - i * 0.5, 0.6, 0.5) assign_material(step.name, base_mat) # ---------- 灯光 ---------- bpy.ops.object.light_add(type='SUN', location=(5, -5, 10)) sun = bpy.context.object sun.name = "light_sun" sun.data.energy = 3 sun.rotation_euler = (0.8, 0.2, 0.5) bpy.ops.object.light_add(type='AREA', location=(-6, 4, 6)) area = bpy.context.object area.name = "light_fill" area.data.energy = 200 area.scale = (3, 3, 3) # ---------- 相机 ---------- camera_data = bpy.data.cameras.new("camera_main") camera_obj = bpy.data.objects.new("camera_main", camera_data) bpy.context.collection.objects.link(camera_obj) camera_obj.location = (9, -8, 5) camera_obj.rotation_euler = (1.15, 0, 0.7) bpy.context.scene.camera = camera_obj # ---------- 渲染设置 ---------- bpy.context.scene.render.engine = 'BLENDER_EEVEE_NEXT' bpy.context.scene.render.resolution_x = 1920 bpy.context.scene.render.resolution_y = 1080 bpy.context.scene.render.image_settings.file_format = 'PNG' bpy.context.scene.render.filepath = "//output/tiangong.png" bpy.ops.render.render(write_still=True) print("渲染完成:output/tiangong.png")如果你让 Codex 生成脚本,它输出的代码可能和上面不完全一样,但结构和逻辑应该类似。核心要素是:清空场景、创建物体、赋予材质、设置灯光相机、渲染输出。
6.5 运行脚本
在项目根目录执行:
blender --background --python scripts/generate_tiangong.py正常执行时,终端会输出 Blender 的启动日志,然后执行 Python 脚本。最后一行会打印:
渲染完成:output/tiangong.png打开output/tiangong.png,你应该能看到一个简化的天宫场景:起伏的云海平面、悬浮的山体、带红色柱子和金色屋顶的宫殿、以及整体偏暖的阳光效果。
6.6 预期效果与调整方向
上面脚本生成的场景属于“简版天宫”,可以作为流程验证使用。如果你希望效果更接近“天宫仙境”,可以从以下几个方向优化:
| 优化方向 | 实现方式 |
|---|---|
| 更细腻的云海 | 增加细分级别,叠加多个 CLOUDS 纹理 |
| 雾效 | 在 EEVEE 中开启体积雾或使用透明平面 |
| 宫殿细节 | 增加斗拱、飞檐翘角、门柱阵列 |
| 山体更自然 | 使用多个球体组合并添加置换修改器 |
| 渲染质量 | 换用 Cycles 引擎,开启光追 |
这些优化同样可以写进 skill 文件,让 Codex 在后续任务中自动遵守。
7. 常见问题与排查思路
在配置和运行过程中,你可能会遇到各种问题。下面整理了几类高频报错和排查思路。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
unable to locate the codex cli binary | IDE 插件找不到 codex 可执行文件 | 在插件设置中指定 codex 路径,或确认 npm 全局 bin 目录在 PATH 中 |
cc switch local proxy failed while handling codex endpoint /responses | Codex 配置的 API 端点或网络代理参数不正确 | 检查config.toml中的base_url、API Key 是否正确,确认终端网络环境正常 |
| 调用 DeepSeek 返回 401 | API Key 未设置或已失效 | 检查环境变量DEEPSEEK_API_KEY是否导出,重新生成 Key |
| 调用 DeepSeek 返回 402 | 账户余额不足 | 前往 DeepSeek 开放平台充值或检查用量 |
ModuleNotFoundError: No module named 'bpy' | 使用系统 Python 直接运行脚本 | 必须使用blender --background --python执行脚本,不要用python script.py |
| Blender 后台运行后没有输出图片 | 渲染输出路径不对或场景中无相机 | 检查render.filepath是否为绝对路径,确认scene.camera已设置 |
| 渲染结果全黑 | 没有灯光或相机位置朝向错误 | 添加光源、调整相机location和rotation_euler |
| Codex 生成的脚本报语法错误 | 大模型生成的代码有笔误 | 复制报错信息让 Codex 自行修复,或在提示词中要求“先生成脚本,再检查语法” |
7.1 Blender 输出路径的建议
使用//开头的路径表示相对于当前 .blend 文件的路径。但在--background模式下,如果还没有保存 .blend 文件,//可能无法正确解析。
更稳妥的做法是使用绝对路径或基于脚本文件所在路径拼接:
import os output_dir = os.path.join(os.path.dirname(__file__), "..", "output") os.makedirs(output_dir, exist_ok=True) bpy.context.scene.render.filepath = os.path.abspath(os.path.join(output_dir, "tiangong.png"))7.2 Codex 执行失败时的排查顺序
如果 Codex 在执行过程中报错,按以下顺序排查:
- 确认 DeepSeek API 能正常响应:单独调用一次
codex exec "1+1=?"。 - 确认 skill 文件路径正确:检查
.codex/skills/目录结构。 - 检查脚本是否生成:查看
scripts/generate_tiangong.py是否存在。 - 手动执行脚本:把 Codex 生成的脚本手动运行一遍,看是否复现报错。
8. 最佳实践与工程建议
8.1 skill 文件要持续迭代
skill 不是写一次就完事的。每次任务结束后,你都应该把这次暴露的问题补进 skill 文件。比如,如果 Codex 经常忘记添加相机,就在 skill 的“注意事项”里写明:脚本末尾必须设置场景相机并确认朝向。
经过几轮迭代,skill 会越来越贴合你的项目需求,Codex 生成的代码质量会明显提升。
8.2 脚本模块化设计
在天宫场景脚本中,我们把云海、山体、宫殿、灯光相机分成了独立段落。在实际项目中,建议拆成多个函数甚至多个文件,方便复用:
create_cloud_sea():生成云海。create_floating_mountain(name, location, scale):生成单个悬浮山。create_palace():生成宫殿主体。setup_camera_and_lights():设置相机和灯光。
这样,当你需要调整某个元素时,不需要改动其他部分。这个规范也可以写进 skill 文件。
8.3 材质和物体命名规范
在自动化建模中,命名规范非常重要。Blender 中同名物体会被自动追加数字后缀,如果没有统一命名规则,Codex 在后续查找物体时会变得混乱。
推荐规则:
- 物体:
obj_前缀 + 类型描述。 - 材质:
material_前缀 + 用途描述。 - 相机:
camera_+ 角度描述。 - 灯光:
light_+ 类型描述。
8.4 控制场景面数
AI 生成的脚本可能会过度细分模型,导致 Blender 卡顿甚至崩溃。建议在 skill 中写入面数约束:
- 每个物体细分级别不超过 3。
- 不使用高精度的布尔运算。
- 远处物体使用较低面数。
需要大量细节时,可以使用置换贴图或法线贴图来模拟,而不是增加真实几何体。
8.5 API Key 安全管理
DeepSeek API Key 属于敏感凭证。建议:
- 使用环境变量或
.env文件注入,不要写死在代码里。 .gitignore中忽略所有包含 Key 的文件。- 如果 Key 意外泄露,立刻在开放平台吊销并重新生成。
8.6 小心自动化命令的破坏性
Blender 脚本通常包含清空场景的操作。如果脚本误操作了重要文件,可能导致数据丢失。在测试阶段,建议:
- 使用
--background模式打开一个空白临时文件。 - 不要在未备份的情况下直接处理重要 .blend 资产。
- 给清空操作加上条件判断,避免误删。
# 清空前做简单确认 if bpy.data.objects: print("即将清空 {} 个物体".format(len(bpy.data.objects)))在自动化场景中,还可以让 Codex 在执行清空前输出将要删除的物体列表,确认后再继续。
8.7 渲染参数统一管理
不同机器、不同 Blender 版本,渲染参数差异较大。建议在 skill 中固定一套标准参数,并在脚本中使用变量控制,方便全局调整:
RENDER_WIDTH = 1920 RENDER_HEIGHT = 1080 RENDER_ENGINE = 'BLENDER_EEVEE_NEXT' RENDER_OUTPUT = "//output/tiangong.png"这样既保证了输出稳定,也方便后续批量替换参数。
9. 总结与下一步学习建议
这套 DeepSeek + Codex + Blender 的组合,核心价值在于把“自然语言描述”转成“可执行的 3D 建模脚本”。从我的实际体验来看,最值得投入精力的不是让 AI 一次生成完美结果,而是把 skill 文件打磨成一个可靠的项目规范。当你把场景拆分规则、命名规范、渲染参数都写清楚后,Codex 的输出会越来越稳定,你甚至可以把整个建模流程交给它独立完成。
接下来你可以继续探索的方向包括:
- 用 OpenAI 的 Codex Skill 机制管理更多建模流程,比如角色建模、场景分镜、批量资产生成。
- 在脚本中接入深度渲染参数,比如 Cycles 光追、HDR 环境贴图、景深相机。
- 把生成的模型批量导出成 glTF / FBX 格式,接入游戏引擎或 Web 3D 展示。
目前这套流程更适合验证原型、快速出效果图、批量生成基础资产。对于需要精细雕刻的高质量模型,还是需要配合人工调整和传统建模技巧。建议你在自己的电脑上先跑一遍天宫场景脚本,再试着修改提示词和 skill 规则,看看 Codex 能不能按照你的要求生成不同风格的场景。动手实践几轮之后,你对这套自动化建模工作流的理解会完全不一样。