Python + Blender 5.0 几何节点全栈实战教程2

第 2 章 从三维三角形开始 ------ 基础几何与节点入门

2.1 手动创建三维三角形(基础网格操作)

三角形是三维图形的 "最小单元"------ 任何复杂的网格模型,本质上都是由无数个三角形面组成的。本节先通过手动操作创建三维三角形,理解 "点→边→面" 的构成逻辑。

2.1.1 手动创建步骤
步骤 操作说明 注意事项
1 切换到 "布局" 工作区,删除默认物体(立方体、灯光、相机) 避免默认物体干扰视图
2 进入顶点编辑模式:点击顶部菜单栏 Add → Mesh → Plane(添加一个平面),选中平面,按 Tab 键进入顶点编辑模式(此时平面的 4 个顶点会显示为橙色) 顶点编辑模式下,可单独选择、移动、删除顶点
3 删除多余顶点:按 A 键取消全选,按住 Shift 键点击平面右上角的两个顶点(选中后显示为黄色),按 X 键 → 选择 "Vertices"(删除顶点) 确保只删除两个顶点,保留两个顶点 + 一条边
4 添加第三个顶点:按 Tab 键退出顶点编辑模式,再按 Tab 键重新进入(确保处于顶点编辑模式),将鼠标移动到 3D 视图中合适位置(如平面上方),按 Shift+A → 选择 "Mesh → Vertex"(添加一个顶点) 新顶点的位置可通过鼠标拖动调整,或在左侧工具栏输入精确坐标
5 连接顶点形成三角形面:按住 Shift 键依次点击三个顶点(按顺时针或逆时针顺序),按 F 键(创建面),此时三个顶点会围成一个三角形面 顶点选择顺序会影响面的法线方向(后续会讲解法线的作用)
6 退出编辑模式:按 Tab 键退出顶点编辑模式,此时会看到一个完整的三维三角形 可通过 W 键(缩放)、E 键(移动)、R 键(旋转)调整三角形位置和大小
7 查看三角形信息:选中三角形,在右侧 "属性" 面板 → Object Data Properties(三角形图标),可查看顶点数(3)、边数(3)、面数(1) 确认三角形的 "点→边→面" 结构正确
2.1.2 三角形法线与方向调整

三角形的 "法线"(Normal)是垂直于面的向量,决定了面的 "正面" 和 "背面"(Blender 中默认正面为可见,背面为透明):

  1. 显示法线:选中三角形,进入顶点编辑模式,点击顶部菜单栏 Overlay → Normals → Face Normals(显示面法线,红色箭头表示法线方向)。
  2. 翻转法线:若法线方向错误(如背面朝向视图,导致三角形透明),选中三角形面(进入面编辑模式:按 Tab → 按 2 键),按 Alt+N → 选择 "Flip Normals"(翻转法线方向)。

2.2 用 Python 脚本生成三角形网格(精准控制)

手动创建三角形无法精确控制顶点坐标,通过 Python 脚本可直接定义三个顶点的坐标,生成精准的三维三角形。

2.2.1 核心原理

Blender 中的网格(Mesh)由 "顶点数据""边数据""面数据" 组成:

  • 顶点数据:存储每个顶点的 (x, y, z) 坐标。
  • 边数据:存储连接的顶点索引(如边由第 0 个和第 1 个顶点组成)。
  • 面数据:存储组成面的顶点索引(如三角形面由第 0、1、2 个顶点组成)。

通过 bpy.data.meshes.new() 创建网格,手动传入顶点、边、面数据,即可生成自定义形状的网格。

2.2.2 完整 Python 脚本(生成等边三角形)

python

运行

复制代码
# Python 脚本生成三维等边三角形(边长为 2,位于 XY 平面)
import bpy
import math

# 步骤 1:清除默认场景
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

# 步骤 2:定义三角形的三个顶点坐标(等边三角形,中心在原点)
# 等边三角形顶点坐标计算:边长为 2,中心在 (0,0,0)
side_length = 2  # 边长
height = (math.sqrt(3) / 2) * side_length  # 等边三角形高
vertices = [
    (-side_length/2, 0, 0),    # 顶点 0:左下角
    (side_length/2, 0, 0),     # 顶点 1:右下角
    (0, height, 0)             # 顶点 2:顶部
]

# 步骤 3:定义边数据(连接顶点的索引)
edges = [
    (0, 1),  # 边 0:顶点 0 → 顶点 1
    (1, 2),  # 边 1:顶点 1 → 顶点 2
    (2, 0)   # 边 2:顶点 2 → 顶点 0
]

# 步骤 4:定义面数据(组成面的顶点索引,按逆时针顺序)
faces = [
    (0, 1, 2)  # 面 0:顶点 0 → 1 → 2(逆时针顺序,确保法线方向正确)
]

# 步骤 5:创建网格数据
mesh = bpy.data.meshes.new(name="TriangleMesh")
mesh.from_pydata(vertices, edges, faces)  # 传入顶点、边、面数据
mesh.update(calc_edges=True)  # 更新网格边缘数据(确保边显示正常)

# 步骤 6:创建物体并关联网格
triangle = bpy.data.objects.new(name="EquilateralTriangle", object_data=mesh)

# 步骤 7:将物体添加到场景
scene = bpy.context.scene
scene.collection.objects.link(triangle)

# 步骤 8:选中并激活物体(方便在视图中查看)
bpy.context.view_layer.objects.active = triangle
triangle.select_set(True)

# 步骤 9:输出三角形信息
print("=" * 50)
print("三维等边三角形生成完成!")
print(f"三角形名称:{triangle.name}")
print(f"顶点坐标:{vertices}")
print(f"边长:{side_length}")
print(f"高:{height:.2f}")
print(f"顶点数:{len(mesh.vertices)}")
print(f"边数:{len(mesh.edges)}")
print(f"面数:{len(mesh.faces)}")
print("=" * 50)
2.2.3 脚本参数说明与修改
参数名称 作用 修改建议
side_length 三角形边长 改为 3,生成更大的三角形
vertices 顶点坐标列表 修改 z 坐标为 1,让三角形位于 z=1 平面
faces 中顶点顺序 决定面的法线方向 改为 (0, 2, 1),观察法线方向变化
2.2.4 常见问题排查
错误现象 可能原因 解决方案
生成后只看到线段,没有面 面数据定义错误(如顶点顺序错误、缺少面数据) 检查 faces 列表是否正确,确保顶点按逆时针顺序排列
三角形透明(看不到面) 法线方向错误(背面朝向视图) 翻转面的顶点顺序,或在脚本中添加 mesh.flip_normals()(创建网格后)
运行脚本报错 "IndexError: list index out of range" 边或面数据中的顶点索引超出顶点列表长度 确保 edgesfaces 中的索引不大于 len(vertices)-1

2.3 几何节点基础节点应用(给三角形 "赋能")

通过几何节点,我们可以给三角形添加动态效果(如移动、旋转、变色),而无需修改原始网格数据。本节将使用基础输入节点、几何节点、输出节点,实现三角形的位置控制和颜色控制。

2.3.1 基础节点分类与核心功能(新手必记)

Blender 5.0 几何节点按功能可分为 8 大类,本节先掌握最基础的 3 类:

节点类别 核心作用 新手必学节点
输入节点(Input Nodes) 提供基础数据(固定值、场景信息、物体信息等) Boolean、Color、Value、Scene Time
几何节点(Geometry Nodes) 处理几何体(读取 / 修改位置、法线、拓扑等) Position、Set Position、Normal
输出节点(Output Nodes) 输出效果或调试数据 Group Output、Viewer
2.3.2 实战案例:彩色三角形(手动创建节点树)

目标:通过几何节点控制三角形的位置和颜色,实现 "固定颜色 + 可调整位置" 的效果。

步骤 操作说明 节点参数设置
1 准备工作:运行 2.2 节的 Python 脚本,生成等边三角形,确保三角形处于选中状态 -
2 添加几何节点修改器:右侧 "属性" 面板 → 修改器 → 添加修改器 → Geometry Nodes 修改器名称:ColorPositionTriangle
3 进入几何节点编辑器:顶部工作区选择 Geometry Nodes,删除默认的 "Group Input" 和 "Group Output" 之间的连线 -
4 添加输入节点:1. Add → Input → Value(命名为 "X 偏移")2. Add → Input → Value(命名为 "Y 偏移")3. Add → Input → Color(命名为 "三角形颜色") -
5 添加几何节点:1. Add → Geometry → Position(读取顶点位置)2. Add → Geometry → Set Position(修改顶点位置)3. Add → Geometry → Set Material(给三角形添加颜色,需先创建材质) -
6 添加向量节点:1. Add → Vector → Combine XYZ(将 X、Y 偏移组合为向量) 节点名称:偏移向量
7 添加材质节点:1. 切换到 "材质" 工作区,点击 New 创建材质(命名为 "TriangleMaterial")2. 进入材质编辑器,添加 Principled BSDF 节点和 Material Output 节点3. 将 "三角形颜色" 节点的输出连接到 Principled BSDF 的 "Base Color" 输入端 材质类型:Principled BSDF(PBR 材质)
8 连接节点(关键步骤):1. Group Input → Position(Geometry 端口)2. "X 偏移" → Combine XYZ(X 端口)3. "Y 偏移" → Combine XYZ(Y 端口)4. Combine XYZ(Vector 端口) → Set Position(Offset 端口)5. Position(Position 端口) → Set Position(Position 端口)6. Set Position(Geometry 端口) → Set Material(Geometry 端口)7. "三角形颜色" → TriangleMaterial 的 Base Color8. Set Material(Geometry 端口) → Group Output(Geometry 端口) 确保所有连线正确,无断开
9 调整参数:1. "X 偏移" 设为 1.5,"Y 偏移" 设为 0.82. "三角形颜色" 设为(255, 100, 100)(红色) 观察 3D 视图,三角形会移动并显示为红色
10 预览效果:点击几何节点编辑器中的 Viewer 节点(若未添加,可添加 Add → Output → Viewer),查看实时效果 -
2.3.3 Python 脚本创建彩色三角形节点树(自动化实现)

手动创建节点树和材质较为繁琐,通过 Python 脚本可一键生成完整的节点树 + 材质:

python

运行

复制代码
# Python 脚本:一键生成彩色可移动三角形(几何节点+材质)
import bpy

# 步骤 1:清除默认场景
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

# 步骤 2:生成等边三角形(复用 2.2 节的代码)
import math
side_length = 2
height = (math.sqrt(3) / 2) * side_length
vertices = [(-side_length/2, 0, 0), (side_length/2, 0, 0), (0, height, 0)]
edges = [(0, 1), (1, 2), (2, 0)]
faces = [(0, 1, 2)]
mesh = bpy.data.meshes.new(name="TriangleMesh")
mesh.from_pydata(vertices, edges, faces)
mesh.update(calc_edges=True)
triangle = bpy.data.objects.new(name="ColorfulTriangle", object_data=mesh)
scene = bpy.context.scene
scene.collection.objects.link(triangle)
bpy.context.view_layer.objects.active = triangle
triangle.select_set(True)

# 步骤 3:创建材质(TriangleMaterial)
def create_triangle_material():
    # 创建材质
    mat = bpy.data.materials.new(name="TriangleMaterial")
    mat.use_nodes = True  # 启用节点材质
    # 清除默认节点
    nodes = mat.node_tree.nodes
    links = mat.node_tree.links
    nodes.clear()
    # 添加 Principled BSDF 节点
    bsdf_node = nodes.new(type='ShaderNodeBsdfPrincipled')
    bsdf_node.location = (-200, 0)
    bsdf_node.inputs['Roughness'].default_value = 0.5  # 粗糙度
    bsdf_node.inputs['Metallic'].default_value = 0.0  # 金属度
    # 添加 Material Output 节点
    output_node = nodes.new(type='ShaderNodeOutputMaterial')
    output_node.location = (0, 0)
    # 连接节点
    links.new(bsdf_node.outputs['BSDF'], output_node.inputs['Surface'])
    return mat, bsdf_node

mat, bsdf_node = create_triangle_material()
# 给三角形添加材质
if triangle.data.materials:
    triangle.data.materials[0] = mat
else:
    triangle.data.materials.append(mat)

# 步骤 4:创建几何节点树
def create_color_position_node_tree(bsdf_node):
    # 创建节点树
    node_tree = bpy.data.node_groups.new(name="ColorPositionNodeTree", type='GeometryNodeTree')
    # 添加 Group Input/Output
    group_input = node_tree.nodes.new(type='NodeGroupInput')
    group_input.location = (-600, 0)
    group_output = node_tree.nodes.new(type='NodeGroupOutput')
    group_output.location = (400, 0)
    # 添加输入节点
    x_offset_node = node_tree.nodes.new(type='ShaderNodeValue')
    x_offset_node.name = "XOffset"
    x_offset_node.label = "X 偏移"
    x_offset_node.location = (-500, 200)
    x_offset_node.outputs[0].default_value = 1.5  # 默认 X 偏移 1.5
    
    y_offset_node = node_tree.nodes.new(type='ShaderNodeValue')
    y_offset_node.name = "YOffset"
    y_offset_node.label = "Y 偏移"
    y_offset_node.location = (-500, 100)
    y_offset_node.outputs[0].default_value = 0.8  # 默认 Y 偏移 0.8
    
    color_node = node_tree.nodes.new(type='ShaderNodeRGB')
    color_node.name = "TriangleColor"
    color_node.label = "三角形颜色"
    color_node.location = (-500, -100)
    color_node.outputs[0].default_value = (1.0, 0.39, 0.39, 1.0)  # RGBA 红色
    # 添加几何节点
    position_node = node_tree.nodes.new(type='GeometryNodeInputPosition')
    position_node.name = "ReadPosition"
    position_node.label = "读取位置"
    position_node.location = (-300, 0)
    
    set_position_node = node_tree.nodes.new(type='GeometryNodeSetPosition')
    set_position_node.name = "SetPosition"
    set_position_node.label = "设置位置"
    set_position_node.location = (-100, 0)
    # 添加向量节点
    combine_xyz_node = node_tree.nodes.new(type='ShaderNodeCombineXYZ')
    combine_xyz_node.name = "OffsetVector"
    combine_xyz_node.label = "偏移向量"
    combine_xyz_node.location = (-300, 150)
    # 添加材质节点(连接几何节点和材质)
    # 注意:几何节点中的 Set Material 节点需要关联材质
    set_material_node = node_tree.nodes.new(type='GeometryNodeSetMaterial')
    set_material_node.name = "SetMaterial"
    set_material_node.label = "设置材质"
    set_material_node.location = (200, 0)
    set_material_node.inputs['Material'].default_value = mat  # 关联创建的材质
    # 连接节点(辅助函数)
    def link_nodes(from_node, from_port, to_node, to_port):
        node_tree.links.new(from_node.outputs[from_port], to_node.inputs[to_port])
    # 连接输入节点 → 偏移向量
    link_nodes(x_offset_node, "Value", combine_xyz_node, "X")
    link_nodes(y_offset_node, "Value", combine_xyz_node, "Y")
    # 连接位置节点 → 设置位置
    link_nodes(group_input, "Geometry", position_node, "Geometry")
    link_nodes(position_node, "Position", set_position_node, "Position")
    link_nodes(combine_xyz_node, "Vector", set_position_node, "Offset")
    # 连接设置位置 → 设置材质
    link_nodes(set_position_node, "Geometry", set_material_node, "Geometry")
    # 连接颜色节点 → 材质
    # 注意:这里需要通过材质的节点树连接,而非几何节点直接连接
    mat.node_tree.links.new(color_node.outputs["Color"], bsdf_node.inputs["Base Color"])
    # 连接设置材质 → 输出
    link_nodes(set_material_node, "Geometry", group_output, "Geometry")
    return node_tree

node_tree = create_color_position_node_tree(bsdf_node)
# 给三角形添加几何节点修改器
geo_mod = triangle.modifiers.new(name="ColorPositionModifier", type='NODES')
geo_mod.node_group = node_tree

# 步骤 5:输出信息
print("=" * 50)
print("彩色可移动三角形生成完成!")
print(f"三角形名称:{triangle.name}")
print(f"材质名称:{mat.name}")
print(f"几何节点树名称:{node_tree.name}")
print(f"默认 X 偏移:{x_offset_node.outputs[0].default_value}")
print(f"默认 Y 偏移:{y_offset_node.outputs[0].default_value}")
print(f"默认颜色:{color_node.outputs[0].default_value[:3]}")
print("=" * 50)

运行脚本后,会自动生成一个红色的等边三角形,且可以在几何节点编辑器中调整 "X 偏移""Y 偏移" 和 "三角形颜色",实时看到效果变化。

2.4 三角形的动态效果:结合场景时间节点

静态三角形不够生动,通过 "场景时间节点"(Scene Time),可以让三角形的位置、颜色随时间变化,实现动态动画效果。

2.4.1 动态效果原理

"场景时间节点" 可获取当前动画的时间信息(如帧编号、秒数),将其作为参数传递给其他节点(如位置节点、颜色节点),即可实现 "时间驱动效果"。Blender 的动画默认帧率为 24 帧 / 秒,即 1 秒 = 24 帧。

2.4.2 实战案例:动态旋转 + 颜色渐变的三角形(手动操作)

目标:三角形绕 Z 轴旋转,同时颜色从红色渐变到蓝色。

步骤 操作说明 节点参数设置
1 准备工作:打开 2.3 节创建的彩色三角形文件,确保三角形和几何节点树处于选中状态 -
2 添加场景时间节点:Add → Input → Scene Time(命名为 "时间节点") -
3 添加数学节点:1. Add → Math → Multiply(命名为 "旋转速度",用于控制旋转快慢)2. Add → Math → Sin(命名为 "颜色渐变",用于生成 0-1 之间的波动值) -
4 添加向量节点:1. Add → Vector → Rotate Euler(命名为 "旋转向量",用于绕 Z 轴旋转) 旋转类型:Z 轴(Euler Z)
5 添加颜色节点:1. Add → Color → Mix(命名为 "颜色混合",用于混合红色和蓝色) 混合类型:叠加(Add)
6 连接节点:1. Scene Time(Seconds 端口) → Multiply(Value 端口)2. Multiply(Value 端口) → Rotate Euler(Angle 端口)3. Position(Position 端口) → Rotate Euler(Vector 端口)4. Rotate Euler(Vector 端口) → Set Position(Position 端口)5. Scene Time(Seconds 端口) → Sin(Value 端口)6. Sin(Value 端口) → Mix(Factor 端口)7. 红色节点 → Mix(Color1 端口)8. 蓝色节点(新增 Add → Input → Color,设为蓝色) → Mix(Color2 端口)9. Mix(Color 端口) → 材质的 Base Color 端口 -
7 调整参数:1. Multiply 节点的第二个 Value 设为 0.5(旋转速度:0.5 圈 / 秒)2. Sin 节点的 Value 设为 1.0(颜色渐变幅度) -
8 播放动画:点击 3D 视图底部的 "播放" 按钮(▶️),观察三角形的旋转和颜色渐变效果 可通过 "时间线" 调整动画时长(默认 250 帧,约 10 秒)
2.4.3 Python 脚本实现动态三角形(自动化动画)

python

运行

复制代码
# Python 脚本:动态旋转+颜色渐变的三角形
import bpy
import math

# 步骤 1:清除默认场景
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()

# 步骤 2:生成等边三角形(复用之前的代码)
side_length = 2
height = (math.sqrt(3) / 2) * side_length
vertices = [(-side_length/2, 0, 0), (side_length/2, 0, 0), (0, height, 0)]
edges = [(0, 1), (1, 2), (2, 0)]
faces = [(0, 1, 2)]
mesh = bpy.data.meshes.new(name="DynamicTriangleMesh")
mesh.from_pydata(vertices, edges, faces)
mesh.update(calc_edges=True)
triangle = bpy.data.objects.new(name="DynamicTriangle", object_data=mesh)
scene = bpy.context.scene
scene.collection.objects.link(triangle)
bpy.context.view_layer.objects.active = triangle
triangle.select_set(True)

# 步骤 3:创建动态材质
def create_dynamic_material():
    mat = bpy.data.materials.new(name="DynamicMaterial")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    links = mat.node_tree.links
    nodes.clear()
    # 添加节点
    bsdf_node = nodes.new(type='ShaderNodeBsdfPrincipled')
    bsdf_node.location = (200, 0)
    bsdf_node.inputs['Roughness'].default_value = 0.5
    bsdf_node.inputs['Metallic'].default_value = 0.0
    
    output_node = nodes.new(type='ShaderNodeOutputMaterial')
    output_node.location = (400, 0)
    
    mix_color_node = nodes.new(type='ShaderNodeMixRGB')
    mix_color_node.name = "ColorMix"
    mix_color_node.label = "颜色混合"
    mix_color_node.location = (0, 0)
    mix_color_node.blend_type = 'ADD'
    
    red_node = nodes.new(type='ShaderNodeRGB')
    red_node.name = "RedColor"
    red_node.label = "红色"
    red_node.location = (-200, 100)
    red_node.outputs[0].default_value = (1.0, 0.39, 0.39, 1.0)
    
    blue_node = nodes.new(type='ShaderNodeRGB')
    blue_node.name = "BlueColor"
    blue_node.label = "蓝色"
    blue_node.location = (-200, -100)
    blue_node.outputs[0].default_value = (0.39, 0.58, 1.0, 1.0)
    
    # 连接材质节点
    links.new(mix_color_node.outputs['Color'], bsdf_node.inputs['Base Color'])
    links.new(bsdf_node.outputs['BSDF'], output_node.inputs['Surface'])
    links.new(red_node.outputs['Color'], mix_color_node.inputs['Color1'])
    links.new(blue_node.outputs['Color'], mix_color_node.inputs['Color2'])
    return mat, mix_color_node

mat, mix_color_node = create_dynamic_material()
triangle.data.materials.append(mat)

# 步骤 4:创建动态几何节点树
def create_dynamic_node_tree(mix_color_node):
    node_tree = bpy.data.node_groups.new(name="DynamicNodeTree", type='GeometryNodeTree')
    # 添加 Group Input/Output
    group_input = node_tree.nodes.new(type='NodeGroupInput')
    group_input.location = (-800, 0)
    group_output = node_tree.nodes.new(type='NodeGroupOutput')
    group_output.location = (400, 0)
    # 添加输入节点
    scene_time_node = node_tree.nodes.new(type='GeometryNodeInputSceneTime')
    scene_time_node.name = "SceneTime"
    scene_time_node.label = "场景时间"
    scene_time_node.location = (-700, 0)
    
    # 添加数学节点
    multiply_node = node_tree.nodes.new(type='ShaderNodeMath')
    multiply_node.name = "RotateSpeed"
    multiply_node.label = "旋转速度"
    multiply_node.location = (-500, 200)
    multiply_node.operation = 'MULTIPLY'
    multiply_node.inputs[1].default_value = 0.5  # 旋转速度:0.5 圈/秒
    
    sin_node = node_tree.nodes.new(type='ShaderNodeMath')
    sin_node.name = "ColorGradient"
    sin_node.label = "颜色渐变"
    sin_node.location = (-500, -200)
    sin_node.operation = 'SINE'
    sin_node.inputs[1].default_value = 1.0  # 渐变幅度
    
    # 添加向量节点
    rotate_euler_node = node_tree.nodes.new(type='ShaderNodeVectorRotate')
    rotate_euler_node.name = "RotateZ"
    rotate_euler_node.label = "绕 Z 轴旋转"
    rotate_euler_node.location = (-300, 0)
    rotate_euler_node.rotation_type = 'EULER_Z'
    
    # 添加几何节点
    position_node = node_tree.nodes.new(type='GeometryNodeInputPosition')
    position_node.name = "ReadPosition"
    position_node.location = (-500, 0)
    
    set_position_node = node_tree.nodes.new(type='GeometryNodeSetPosition')
    set_position_node.name = "SetPosition"
    set_position_node.location = (-100, 0)
    
    set_material_node = node_tree.nodes.new(type='GeometryNodeSetMaterial')
    set_material_node.name = "SetMaterial"
    set_material_node.location = (200, 0)
    set_material_node.inputs['Material'].default_value = mat
    
    # 连接节点函数
    def link(from_node, from_port, to_node, to_port):
        node_tree.links.new(from_node.outputs[from_port], to_node.inputs[to_port])
    
    # 连接时间 → 旋转
    link(scene_time_node, "Seconds", multiply_node, "Value")
    link(multiply_node, "Value", rotate_euler_node, "Angle")
    link(position_node, "Position", rotate_euler_node, "Vector")
    link(rotate_euler_node, "Vector", set_position_node, "Position")
    
    # 连接时间 → 颜色渐变
    link(scene_time_node, "Seconds", sin_node, "Value")
    # 注意:Sin 输出范围是 [-1,1],需要归一化到 [0,1](添加 Add + Multiply)
    add_node = node_tree.nodes.new(type='ShaderNodeMath')
    add_node.name = "NormalizeAdd"
    add_node.label = "归一化(+1)"
    add_node.location = (-300, -200)
    add_node.operation = 'ADD'
    add_node.inputs[1].default_value = 1.0
    
    multiply_norm_node = node_tree.nodes.new(type='ShaderNodeMath')
    multiply_norm_node.name = "NormalizeMult"
    multiply_norm_node.label = "归一化(×0.5)"
    multiply_norm_node.location = (-100, -200)
    multiply_norm_node.operation = 'MULTIPLY'
    multiply_norm_node.inputs[1].default_value = 0.5
    
    link(sin_node, "Value", add_node, "Value")
    link(add_node, "Value", multiply_norm_node, "Value")
    link(multiply_norm_node, "Value", mix_color_node, "Fac")  # 连接到颜色混合的 Factor 端口
    
    # 连接其他节点
    link(group_input, "Geometry", position_node, "Geometry")
    link(set_position_node, "Geometry", set_material_node, "Geometry")
    link(set_material_node, "Geometry", group_output, "Geometry")
    
    return node_tree

node_tree = create_dynamic_node_tree(mix_color_node)
# 添加几何节点修改器
geo_mod = triangle.modifiers.new(name="DynamicModifier", type='NODES')
geo_mod.node_group = node_tree

# 步骤 5:设置动画参数
scene.frame_start = 1  # 动画起始帧
scene.frame_end = 500  # 动画结束帧(约 20 秒)
scene.render.fps = 24  # 帧率

# 步骤 6:输出信息
print("=" * 50)
print("动态旋转+颜色渐变三角形生成完成!")
print(f"动画时长:{scene.frame_end - scene.frame_start + 1} 帧({((scene.frame_end - scene.frame_start + 1)/24):.1f} 秒)")
print(f"旋转速度:0.5 圈/秒")
print(f"颜色渐变:红色 ↔ 蓝色")
print("点击播放按钮查看动画效果!")
print("=" * 50)

运行脚本后,点击 3D 视图底部的播放按钮,即可看到三角形绕 Z 轴缓慢旋转,同时颜色在红色和蓝色之间平滑渐变。

2.5 本章小结与进阶方向

2.5.1 核心知识点回顾
  • 掌握了三维三角形的手动创建和 Python 脚本生成,理解了 "点→边→面" 的网格结构。
  • 熟悉了几何节点的基础分类(输入、几何、输出节点),能手动和通过 Python 脚本创建简单节点树。
  • 学会了用几何节点控制模型的位置和颜色,结合场景时间节点实现动态动画效果。
  • 理解了 Python 脚本与几何节点、材质的联动逻辑,能自动化生成完整的三维效果。
2.5.2 进阶方向
  1. 给动态三角形添加缩放效果(结合场景时间节点和缩放节点)。
  2. 实现三角形沿路径移动(添加曲线节点,让三角形跟随曲线运动)。
  3. 批量生成多个动态三角形,每个三角形的旋转速度和颜色不同。
  4. 给三角形添加阴影和反射效果(调整材质的粗糙度、金属度参数)。
相关推荐
2301_790300964 小时前
Python单元测试(unittest)实战指南
jvm·数据库·python
VCR__5 小时前
python第三次作业
开发语言·python
韩立学长5 小时前
【开题答辩实录分享】以《助农信息发布系统设计与实现》为例进行选题答辩实录分享
python·web
2401_838472515 小时前
使用Scikit-learn构建你的第一个机器学习模型
jvm·数据库·python
u0109272715 小时前
使用Python进行网络设备自动配置
jvm·数据库·python
工程师老罗5 小时前
优化器、反向传播、损失函数之间是什么关系,Pytorch中如何使用和设置?
人工智能·pytorch·python
Fleshy数模5 小时前
我的第一只Python爬虫:从Requests库到爬取整站新书
开发语言·爬虫·python
CoLiuRs5 小时前
Image-to-3D — 让 2D 图片跃然立体*
python·3d·flask
小鸡吃米…6 小时前
机器学习 —— 训练与测试
人工智能·python·机器学习
七夜zippoe6 小时前
Docker容器化Python应用最佳实践:从镜像优化到安全防护
python·docker·云原生·eureka·容器化