> 技术文档 > Python 编程绘制 Blender 3D 模型全攻略_blender python

Python 编程绘制 Blender 3D 模型全攻略_blender python

目录

一、环境准备

1. 安装 Blender

2. Blender Python 环境

3. 核心模块

二、基础操作:创建简单 3D 对象

1. 创建立方体

2. 创建球体

三、使用 Bmesh 创建和修改网格

1. 创建自定义网格

2. 修改现有网格

四、添加材质和纹理

1. 创建简单材质

2. 添加纹理

五、动画制作

1. 关键帧动画(位置)

2. 旋转动画

六、批量处理与自动化

1. 批量创建对象

2. 批量修改属性

七、高级网格操作技术

1. 细分曲面与平滑处理

2. 顶点权重与骨骼绑定

八、程序化生成复杂模型

1. 分形几何生成(科赫雪花)

2. 植物生成

九、物理模拟与动力学

1. 布料模拟

2. 粒子系统

十、渲染与后期处理

1. 高级渲染设置

2. 后期合成

十一、导出与集成

1. 导出为常见格式

2. 批量渲染脚本

十二、实用技巧与最佳实践


一、环境准备

1. 安装 Blender

从Blender 官网下载并安装对应系统版本。

2. Blender Python 环境

Blender 内置 Python 解释器,通过 \"文本编辑器\" 面板编写 / 运行脚本:

# 简单测试脚本import bpyprint(\"Blender Python环境正常\")
3. 核心模块
  • bpy:访问 Blender 所有数据和功能
  • bmesh:高效处理 3D 网格模型

二、基础操作:创建简单 3D 对象

1. 创建立方体
import bpy# 清除场景bpy.ops.object.select_all(action=\'SELECT\')bpy.ops.object.delete()# 创建立方体bpy.ops.mesh.primitive_cube_add(size=2)
2. 创建球体
import bpy# 清除场景bpy.ops.object.select_all(action=\'SELECT\')bpy.ops.object.delete()# 创建球体bpy.ops.mesh.primitive_sphere_add(radius=1, location=(0, 0, 0))

三、使用 Bmesh 创建和修改网格

1. 创建自定义网格
import bpyimport bmesh# 创建网格数据和对象mesh = bpy.data.meshes.new(\"CustomMesh\")obj = bpy.data.objects.new(\"CustomObject\", mesh)bpy.context.collection.objects.link(obj)# 创建Bmesh并添加顶点和面bm = bmesh.new()v1 = bm.verts.new((0, 0, 0))v2 = bm.verts.new((1, 0, 0))v3 = bm.verts.new((1, 1, 0))v4 = bm.verts.new((0, 1, 0))bm.faces.new([v1, v2, v3, v4])# 更新网格bm.to_mesh(mesh)bm.free()
2. 修改现有网格
import bpyimport bmesh# 获取当前对象obj = bpy.context.active_objectmesh = obj.data# 进入编辑模式bpy.ops.object.mode_set(mode=\'EDIT\')bm = bmesh.from_mesh(mesh)# 修改顶点位置for v in bm.verts: v.co.x += 0.1# 更新网格并退出编辑模式bm.to_mesh(mesh)bm.free()bpy.ops.object.mode_set(mode=\'OBJECT\')

四、添加材质和纹理

1. 创建简单材质

python

运行

import bpy# 创建材质mat = bpy.data.materials.new(name=\"RedMaterial\")mat.diffuse_color = (1, 0, 0, 1) # 红色# 分配给当前对象obj = bpy.context.active_objectif obj.data.materials: obj.data.materials[0] = matelse: obj.data.materials.append(mat)
2. 添加纹理
import bpy# 创建材质mat = bpy.data.materials.new(name=\"TexturedMaterial\")mat.use_nodes = Truenodes = mat.node_tree.nodeslinks = mat.node_tree.links# 清除默认节点for node in nodes: nodes.remove(node)# 创建节点bsdf = nodes.new(\'ShaderNodeBsdfDiffuse\')texture = nodes.new(\'ShaderNodeTexImage\')output = nodes.new(\'ShaderNodeOutputMaterial\')# 加载纹理图片(需替换路径)try: image = bpy.data.images.load(\"C:/path/to/your/texture.jpg\") texture.image = imageexcept: print(\"无法加载纹理图片\")# 连接节点links.new(texture.outputs[\"Color\"], bsdf.inputs[\"Color\"])links.new(bsdf.outputs[\"BSDF\"], output.inputs[\"Surface\"])# 分配材质obj = bpy.context.active_objectobj.data.materials.append(mat)

五、动画制作

1. 关键帧动画(位置)
import bpyobj = bpy.context.active_object# 设置第1帧位置obj.location = (0, 0, 0)obj.keyframe_insert(data_path=\"location\", frame=1)# 设置第20帧位置obj.location = (5, 0, 0)obj.keyframe_insert(data_path=\"location\", frame=20)
2. 旋转动画
import bpyobj = bpy.context.active_object# 设置第1帧旋转obj.rotation_euler = (0, 0, 0)obj.keyframe_insert(data_path=\"rotation_euler\", frame=1)# 设置第30帧旋转(180度)obj.rotation_euler = (0, 0, 3.14159)obj.keyframe_insert(data_path=\"rotation_euler\", frame=30)

六、批量处理与自动化

1. 批量创建对象
import bpy# 清除场景bpy.ops.object.select_all(action=\'SELECT\')bpy.ops.object.delete()# 创建5个立方体for i in range(5): bpy.ops.mesh.primitive_cube_add(size=1, location=(i*2, 0, 0))
2. 批量修改属性
import bpy# 为所有立方体添加不同颜色材质for i, obj in enumerate(bpy.data.objects): if obj.type == \'MESH\' and \"Cube\" in obj.name: mat = bpy.data.materials.new(name=f\"Mat_{i}\") mat.diffuse_color = (i/5, 0, 0, 1) # 红色渐变 obj.data.materials.append(mat)

七、高级网格操作技术

1. 细分曲面与平滑处理
import bpy# 创建基础立方体bpy.ops.mesh.primitive_cube_add(size=2)obj = bpy.context.active_object# 添加细分曲面修改器subdivision = obj.modifiers.new(name=\"Subdivision\", type=\'SUBSURF\')subdivision.levels = 2# 应用平滑着色bpy.ops.object.shade_smooth()# 添加材质mat = bpy.data.materials.new(name=\"SmoothMaterial\")mat.use_nodes = Truebsdf = mat.node_tree.nodes[\"Principled BSDF\"]bsdf.inputs[\'Base Color\'].default_value = (0.3, 0.6, 0.9, 1.0)obj.data.materials.append(mat)
2. 顶点权重与骨骼绑定
import bpy# 创建网格bpy.ops.mesh.primitive_cube_add(size=2)obj = bpy.context.active_object# 创建骨骼bpy.ops.object.armature_add()armature = bpy.context.active_objectarmature.name = \"Rig\"# 切换到姿势模式并旋转骨骼bpy.ops.object.mode_set(mode=\'POSE\')bone = armature.pose.bones[0]bone.rotation_euler = (0.785, 0, 0) # 45度bpy.ops.object.mode_set(mode=\'OBJECT\')# 设置父子关系obj.parent = armatureobj.parent_type = \'ARMATURE\'

八、程序化生成复杂模型

1. 分形几何生成(科赫雪花)
import bpyimport mathdef koch_curve(p1, p2, depth): if depth == 0: return [p1, p2] dx = (p2[0] - p1[0]) / 3 dy = (p2[1] - p1[1]) / 3 a = (p1[0] + dx, p1[1] + dy, 0) c = (p2[0] - dx, p2[1] - dy, 0) angle = math.radians(60) bx = a[0] + dx * math.cos(angle) - dy * math.sin(angle) by = a[1] + dx * math.sin(angle) + dy * math.cos(angle) b = (bx, by, 0) return (koch_curve(p1, a, depth-1) + koch_curve(a, b, depth-1) + koch_curve(b, c, depth-1) + koch_curve(c, p2, depth-1))# 创建网格mesh = bpy.data.meshes.new(\"KochSnowflake\")obj = bpy.data.objects.new(\"KochSnowflake\", mesh)bpy.context.collection.objects.link(obj)# 生成科赫雪花size = 3depth = 3points = []for i in range(3): angle1 = math.radians(120 * i) angle2 = math.radians(120 * (i + 1)) p1 = (math.cos(angle1) * size, math.sin(angle1) * size, 0) p2 = (math.cos(angle2) * size, math.sin(angle2) * size, 0) points += koch_curve(p1, p2, depth)# 移除重复顶点vertices = list(set(points))edges = []for i in range(len(points) - 1): idx1 = vertices.index(points[i]) idx2 = vertices.index(points[i+1]) edges.append((idx1, idx2))edges.append((vertices.index(points[-1]), vertices.index(points[0])))# 更新网格mesh.from_pydata(vertices, edges, [])mesh.update()
2. 植物生成
import bpyimport randomdef create_branch(parent, length, thickness, level, max_levels): if level > max_levels: return # 创建分支 bpy.ops.mesh.primitive_cylinder_add(radius=thickness, depth=length) branch = bpy.context.active_object # 设置父对象 if parent: branch.parent = parent branch.location.z = length / 2 bpy.ops.object.select_all(action=\'DESELECT\') branch.select_set(True) parent.select_set(True) bpy.context.view_layer.objects.active = parent bpy.ops.object.parent_set(type=\'OBJECT\') # 随机旋转 angle_x = random.uniform(-0.5, 0.5) angle_y = random.uniform(-0.5, 0.5) angle_z = random.uniform(-3.14, 3.14) branch.rotation_euler = (angle_x, angle_y, angle_z) bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) # 递归创建子分支 num_children = random.randint(2, 4) for _ in range(num_children): child_length = length * random.uniform(0.6, 0.8) child_thickness = thickness * random.uniform(0.7, 0.9) create_branch(branch, child_length, child_thickness, level + 1, max_levels)# 创建树干bpy.ops.mesh.primitive_cylinder_add(radius=0.15, depth=1.5)trunk = bpy.context.active_object# 创建树叶材质leaf_material = bpy.data.materials.new(name=\"LeafMaterial\")leaf_material.use_nodes = Truebsdf = leaf_material.node_tree.nodes[\"Principled BSDF\"]bsdf.inputs[\'Base Color\'].default_value = (0.1, 0.6, 0.1, 1.0)# 生成树枝create_branch(trunk, 1.0, 0.1, 1, 4)# 添加树叶bpy.ops.mesh.primitive_ico_sphere_add(radius=0.2)leaf = bpy.context.active_objectleaf.data.materials.append(leaf_material)leaf.parent = trunkleaf.location.z = 2.0

九、物理模拟与动力学

1. 布料模拟
import bpy# 创建布料平面bpy.ops.mesh.primitive_plane_add(size=2)cloth = bpy.context.active_objectcloth.name = \"Cloth\"# 添加细分曲面subdivision = cloth.modifiers.new(name=\"Subdivision\", type=\'SUBSURF\')subdivision.levels = 3# 添加布料修改器cloth.modifiers.new(name=\"Cloth\", type=\'CLOTH\')cloth.cloth.settings.quality = 10cloth.cloth.settings.mass = 0.5# 创建碰撞球体bpy.ops.mesh.primitive_sphere_add(radius=0.5, location=(0, 0, 1))sphere = bpy.context.active_objectsphere.name = \"CollisionSphere\"sphere.modifiers.new(name=\"Collision\", type=\'COLLISION\')# 创建地面bpy.ops.mesh.primitive_plane_add(size=5, location=(0, 0, -0.5))ground = bpy.context.active_objectground.name = \"Ground\"ground.modifiers.new(name=\"Collision\", type=\'COLLISION\')# 设置布料材质cloth_material = bpy.data.materials.new(name=\"ClothMaterial\")cloth_material.use_nodes = Truebsdf = cloth_material.node_tree.nodes[\"Principled BSDF\"]bsdf.inputs[\'Base Color\'].default_value = (0.2, 0.4, 0.8, 1.0)cloth.data.materials.append(cloth_material)# 设置重力和帧数bpy.context.scene.gravity = (0, 0, -9.81)bpy.context.scene.frame_start = 1bpy.context.scene.frame_end = 250
2. 粒子系统
import bpy# 创建发射器bpy.ops.mesh.primitive_ico_sphere_add(radius=1)emitter = bpy.context.active_objectemitter.name = \"ParticleEmitter\"# 添加粒子系统emitter.modifiers.new(name=\"Particles\", type=\'PARTICLE_SYSTEM\')ps = emitter.particle_systems[0]settings = ps.settings# 配置粒子settings.type = \'EMITTER\'settings.count = 1000settings.frame_start = 1settings.frame_end = 10settings.lifetime = 200settings.lifetime_random = 0.5settings.normal_factor = 0.0settings.object_align_factor[2] = 1.0 # 沿Z轴发射# 创建粒子材质particle_material = bpy.data.materials.new(name=\"ParticleMaterial\")particle_material.use_nodes = Truebsdf = particle_material.node_tree.nodes[\"Principled BSDF\"]bsdf.inputs[\'Base Color\'].default_value = (1.0, 0.8, 0.2, 1.0)bsdf.inputs[\'Roughness\'].default_value = 0.2# 创建粒子对象bpy.ops.mesh.primitive_ico_sphere_add(radius=0.05)particle_object = bpy.context.active_objectparticle_object.name = \"Particle\"particle_object.data.materials.append(particle_material)# 设置粒子为对象settings.render_type = \'OBJECT\'settings.instance_object = bpy.data.objects[\"Particle\"]# 添加力场bpy.ops.object.effector_add(type=\'FORCE\', location=(0, 0, 0))force_field = bpy.context.active_objectforce_field.name = \"ForceField\"force_field.field.strength = 5.0

十、渲染与后期处理

1. 高级渲染设置
import bpy# 设置渲染引擎为Cyclesbpy.context.scene.render.engine = \'CYCLES\'# 配置GPU渲染preferences = bpy.context.preferencescycles_preferences = preferences.addons[\'cycles\'].preferencescycles_preferences.get_devices()cycles_preferences.compute_device_type = \'CUDA\' # 或\'OPTIX\'# 选择所有GPU设备for device in cycles_preferences.devices: if device.type == \'CUDA\': # 或\'OPTIX\' device.use = True# 设置渲染参数bpy.context.scene.cycles.samples = 512bpy.context.scene.cycles.max_bounces = 8bpy.context.scene.cycles.min_bounces = 3bpy.context.scene.cycles.diffuse_bounces = 4bpy.context.scene.cycles.glossy_bounces = 4bpy.context.scene.cycles.transmission_bounces = 8bpy.context.scene.cycles.volume_bounces = 0bpy.context.scene.cycles.caustics_reflective = Falsebpy.context.scene.cycles.caustics_refractive = False# 设置输出分辨率bpy.context.scene.render.resolution_x = 1920bpy.context.scene.render.resolution_y = 1080bpy.context.scene.render.resolution_percentage = 100# 添加环境光bpy.ops.object.light_add(type=\'AREA\', location=(0, 0, 5))light = bpy.context.active_objectlight.data.energy = 1000light.scale = (10, 10, 10)# 设置世界背景bpy.context.scene.world.use_nodes = Truebg = bpy.context.scene.world.node_tree.nodes[\'Background\']bg.inputs[\'Color\'].default_value = (0.05, 0.05, 0.1, 1)bg.inputs[\'Strength\'].default_value = 2# 设置相机bpy.ops.object.camera_add(location=(5, 5, 5))camera = bpy.context.active_objectbpy.context.scene.camera = camera# 设置相机目标bpy.ops.object.empty_add(type=\'SPHERE\', location=(0, 0, 0))target = bpy.context.active_objecttarget.name = \"CameraTarget\"# 添加跟踪约束track_constraint = camera.constraints.new(type=\'TRACK_TO\')track_constraint.target = targettrack_constraint.track_axis = \'TRACK_NEGATIVE_Z\'track_constraint.up_axis = \'UP_Y\'
2. 后期合成
import bpy# 启用合成节点bpy.context.scene.use_nodes = Truetree = bpy.context.scene.node_treelinks = tree.links# 清除默认节点for node in tree.nodes: tree.nodes.remove(node)# 创建节点render_layers = tree.nodes.new(\'CompositorNodeRLayers\')color_correction = tree.nodes.new(\'CompositorNodeColorCorrection\')glare = tree.nodes.new(\'CompositorNodeGlare\')composite = tree.nodes.new(\'CompositorNodeComposite\')# 设置节点参数color_correction.master_saturation = 1.2color_correction.master_gain = 1.1glare.size = 4glare.threshold = 0.8# 连接节点links.new(render_layers.outputs[\'Image\'], color_correction.inputs[\'Image\'])links.new(color_correction.outputs[\'Image\'], glare.inputs[\'Image\'])links.new(glare.outputs[\'Image\'], composite.inputs[\'Image\'])# 添加景深效果bpy.context.scene.camera.data.dof.use_dof = Truebpy.context.scene.camera.data.dof.focus_object = bpy.data.objects[\"CameraTarget\"]bpy.context.scene.camera.data.dof.aperture_fstop = 1.4# 添加运动模糊bpy.context.scene.render.use_motion_blur = Truebpy.context.scene.render.motion_blur_samples = 16# 设置输出路径bpy.context.scene.render.filepath = \"//render_output/\"bpy.context.scene.render.image_settings.file_format = \'PNG\'

十一、导出与集成

1. 导出为常见格式
import bpy# 导出为OBJ格式bpy.ops.export_scene.obj( filepath=\"//exported_model.obj\", use_selection=True, use_materials=True)# 导出为FBX格式bpy.ops.export_scene.fbx( filepath=\"//exported_model.fbx\", use_selection=True, axis_forward=\'-Z\', axis_up=\'Y\')
2. 批量渲染脚本
import bpyimport os# 设置渲染输出路径output_folder = \"//render_sequences/\"if not os.path.exists(bpy.path.abspath(output_folder)): os.makedirs(bpy.path.abspath(output_folder))# 渲染当前帧bpy.context.scene.render.filepath = output_folder + \"frame_\"bpy.ops.render.render(write_still=True)# 渲染动画bpy.ops.render.render(animation=True)

十二、实用技巧与最佳实践

  1. 脚本调试技巧

    import bpydef debug_print(message): print(f\"[DEBUG] {message}\")# 使用示例obj = bpy.context.active_objectdebug_print(f\"当前活动对象: {obj.name}\")
  2. 错误处理

    try: # 可能出错的代码 bpy.ops.mesh.primitive_cube_add()except Exception as e: print(f\"发生错误: {e}\")
  3. 性能优化

    # 使用bmesh替代ops进行网格操作import bmeshmesh = bpy.context.active_object.databm = bmesh.new()bm.from_mesh(mesh)# 高效操作顶点for v in bm.verts: v.co.z += 0.1bm.to_mesh(mesh)bm.free()

通过以上内容,你已掌握使用 Python 编程创建、修改和渲染 Blender 3D 模型的核心技术。建议通过实际项目练习巩固这些知识,并参考Blender 官方 Python API 文档获取更多细节。