【Blender】通过 Python 脚本为对象应用材质


theme: orange
highlight: zenburn

本文正在参加「金石计划 . 瓜分6万现金大奖」

前置知识:如何添加材质

添加材质的步骤

具体可以分解为以下几步

  • 创建新材质
  • 制作可用的节点
  • 添加对象
  • 设置节点的值
  • 将材质应用在物体上

Principled BSDF 节点的内容

节点的每一项参数都是从 0 开始分配的一个编号(Index)。
Principled BSDF 为例,让我们来看看该如何使用它。

image.png

如上图所示,主要使用的参数项所对应的编号如下

节点参数 参数编号
Base Color 0
Subsurface 1
Metallic 4
Roughness 7
Transmission 15

然后我们就可以使用该节点的 nodes["Principled BSDF"].inputs[index].default_value 来为它们指定具体的值。

用 Python 制作玻璃材质的示例

例子1:创建一个简单的玻璃球(ico_sphere)

image.png

完整代码与注释

import bpy

# 制作新的材质
material_glass = bpy.data.materials.new('Green')
# 开启使用节点
material_glass.use_nodes = True
# 添加对象(ico_sphere)
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=1, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))

# 设定节点的值
# 创建变量 p_BSDF ,减少重复输入以下长串的名称
p_BSDF = material_glass.node_tree.nodes["Principled BSDF"]
# 0→BaseColor / 7→roughness(=粗糙度) / 15→transmission(=传播)
#default_value = (R, G, B, A)
p_BSDF.inputs[0].default_value = (0, 1, 0, 1)
p_BSDF.inputs[7].default_value = 0
p_BSDF.inputs[15].default_value = 1
# 给对象添加材质元素
bpy.context.object.data.materials.append(material_glass)

例子2:在三维空间中排列玻璃立方体的程序

image.png

完整代码与注释

import bpy

for i in range(0,5):
    for j in range(0,5):
        for k in range(0,5):
            # 制作新材质
            material_glass = bpy.data.materials.new('Red')
            # 开启使用节点
            material_glass.use_nodes = True
            bpy.ops.mesh.primitive_cube_add(
                size=0.8,
                # 分别决定立方体在 x、y、z 上的坐标
                location=(i, j, k),
                )
            p_BSDF = material_glass.node_tree.nodes["Principled BSDF"]
            p_BSDF.inputs[0].default_value = (1, 0, 0, 1)
            p_BSDF.inputs[7].default_value = 0
            p_BSDF.inputs[15].default_value = 1
            bpy.context.object.data.materials.append(material_glass)

不过以上代码会 每个立方体都创建一个材质

image.png

如果只想让它们 共享 一个材质的话,可以将 材质创建 部分的代码移到循环块之外,即修改为如下

import bpy

# 制作新材质
material_glass = bpy.data.materials.new('Red')
# 开启使用节点
material_glass.use_nodes = True
p_BSDF = material_glass.node_tree.nodes["Principled BSDF"]    
      
for i in range(0,5):
    for j in range(0,5):
        for k in range(0,5):

            bpy.ops.mesh.primitive_cube_add(
                size=0.8,
                # 分别决定立方体在 x、y、z 上的坐标
                location=(i, j, k),
                )
            
            p_BSDF.inputs[0].default_value = (1, 0, 0, 1)
            p_BSDF.inputs[7].default_value = 0
            p_BSDF.inputs[15].default_value = 1
            bpy.context.object.data.materials.append(material_glass)

注意:添加了立方体之后还可以接着对它进行 缩放旋转平移 等的变换

bpy.ops.transform.resize(value=(2.0,1.0,0.1)) 
bpy.ops.transform.rotate(value=3.1415/6, orient_axis='Y') 
bpy.ops.transform.translate(value=(0,0,5))

Bonus

添加文字

image.png

代码与注释如下

import bpy

# 添加文本,以编辑模式进行编辑
bpy.ops.object.text_add(enter_editmode = True,location = (0,0,0))
# 删除初始文本
bpy.ops.font.delete(type = 'PREVIOUS_WORD')
# 输入文本
bpy.ops.font.text_insert(text = 'Blender')
# 结束编辑模式
bpy.ops.object.editmode_toggle()

为文字关联材质

image.png

结合前文的知识与代码,我们可以写出如下代码

import bpy

# 创建材质节点
material_glass = bpy.data.materials.new('Blue')
material_glass.use_nodes = True

# 添加文字
bpy.ops.object.text_add(enter_editmode = True,location = (0,0,0))
bpy.ops.font.delete(type = 'PREVIOUS_WORD')
bpy.ops.font.text_insert(text = 'Blender')
bpy.ops.object.editmode_toggle()

# 操作材质节点
p_BSDF = material_glass.node_tree.nodes["Principled BSDF"]
p_BSDF.inputs[4].default_value = 1
p_BSDF.inputs[7].default_value = 0
p_BSDF.inputs[0].default_value = (0, 0, 1, 1)
bpy.context.object.data.materials.append(material_glass)

清理场景中的网格

挺方便的工具代码,可以放在脚本的开头执行,这样就不用每次都手动清除之前创建的网格

## 已存在的网格,通通都删除
for item in bpy.data.meshes:
    bpy.data.meshes.remove(item)

如果想 删除指定 的网格,可以修改如下代码

# 移除名为 "Cube" 的网格
if "Cube" in bpy.data.meshes:
    mesh = bpy.data.meshes["Cube"]
    print("removing mesh", mesh)
    bpy.data.meshes.remove(mesh)
© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容