オブジェクトに画像を設定する操作をbpy (Blender Python API)を用いてテキストベースで行っていきます。
動作確認環境 : Blender 4.2
イメージテクスチャの追加
まず、イメージテクスチャ(ノード)の追加して、そのテクスチャに画像を設定します。
画像をBlenderに取り込んで、テクスチャに割り当てるまでは、どのようなオブジェクトであっても共通の操作になるので、bpyを用いて関数として操作をまとめておきます。
このように画像をBlenderに取り込んで、特定の面に設定したマテリアルのイメージテクスチャノードに画像を割り当てるところまでを行います。
Python :
def add_image_texture(
material_name
, image_path
, texture_node_name="TX_Image_00"
, node_location=(-300, 300)
):
# マテリアルを取得、または作成
material = bpy.data.materials.get(material_name)
if material is None:
material = bpy.data.materials.new(name=material_name)
# ノードを使用する設定
material.use_nodes = True
nodes = material.node_tree.nodes
# 既存のImage Textureノードがあるか確認、なければ新規作成
texture_node = nodes.get(texture_node_name)
if texture_node is None:
texture_node = nodes.new(type='ShaderNodeTexImage')
texture_node.name = texture_node_name
# 画像をロード(Blender内部データベースに登録)
img = bpy.data.images.load(image_path)
# Image Textureノードに画像を設定
texture_node.image = img
# ノードの位置を調整(オプション)
texture_node.location = node_location
- material_name
- マテリアル名でマテリアルを指定
- image_path
- 画像ファイルパス
- texture_node_name
- イメージテクスチャ名に付ける任意の名前
- node_location
- テクスチャノード配置位置
画像のパスは、このようにbpyの実行スクリプトのある位置から、相対位置で指定するようにしておくとGitなどでスクリプトごとディレクトリを管理しやすくなります。
実行スクリプトのディレクトリ位置取得:
# スクリプト名
script_text = bpy.context.space_data.text
# スクリプトのディレクトリを取得
script_dir = os.path.dirname(bpy.path.abspath(script_text.filepath))
image_path= script_dir + "/image_name.png"
具体的な使い方の例はこちら(本記事末尾)にあります。
面に画像を割り当てるノード設定
イメージテクスチャを追加後、他のノードと適切に接続してオブジェクトにマテリアルを割り当てます。
ノードの組み合わせにも様々なものがあると思いますが、ここでは、次のような構成を作成していきます。
▼ノードの追加と接続方法
マテリアルの追加後、ノードの追加と接続処理は次のように行っていきます。
Python :
# イメージテクスチャ追加
add_image_texture(
material_name="MT_cube_00_Content_00"
, image_path= script_dir + "/image_name.png"
, texture_node_name="TX_Image_00"
, node_location=(-400,300)
)
# テクスチャ追加
add_new_texture(
material_name="MT_cube_00_Content_00"
, texture_name="ShaderNodeMix"
, texture_node_name="Mix_RGB_00"
, node_location=(-150, 600)
, settings=[{"name": "data_type", "value": 'RGBA'}]
)
# ノードのリンク
node_link_func(
material_name="MT_cube_00_Content_00"
, texture_node_name_out="Mix_RGB_00"
, texture_node_name_in="Principled BSDF"
, output_link="Result"
, input_link="Base Color"
)
# ノードのリンク
node_link_func(
material_name="MT_cube_00_Content_00"
, texture_node_name_out="TX_Image_00"
, texture_node_name_in="Mix_RGB_00"
, output_link="Color"
, input_link="B"
)
# テクスチャ追加
add_new_texture(
material_name="MT_cube_00_Content_00"
, texture_name="ShaderNodeMapping"
, texture_node_name="Mapping_00"
, node_location=(-600, 300)
)
# ノードのリンク
node_link_func(
material_name="MT_cube_00_Content_00"
, texture_node_name_out="Mapping_00"
, texture_node_name_in="TX_Image_00"
, output_link="Vector"
, input_link="Vector"
)
# テクスチャ追加
add_new_texture(
material_name="MT_cube_00_Content_00"
, texture_name="ShaderNodeTexCoord"
, texture_node_name="TX_Coord_00"
, node_location=(-800, 300)
)
# ノードのリンク
node_link_func(
material_name="MT_cube_00_Content_00"
, texture_node_name_out="TX_Coord_00"
, texture_node_name_in="Mapping_00"
, output_link="UV"
, input_link="Vector"
)
これらのノードをイメージテクスチャノード周囲に追加することで、Mappingテクスチャを用いて、画像の回転、位置合わせ、サイズ変更を行ったり、ShaderNodeMixを用いて、画像の色味を調節するなど画像に対して見栄えの調整を加えることができるようになります。
画像サイズ/位置/方向調整
画像をイメージテクスチャノードに追加しただけでは、選択した面に対してサイズや方向があっていないので、面に対して適切な画像位置が表示されるように調節していきます。
方法1:
Mappingノードの値を変更する方法
▼ノードの値の変更方法
上で追加したノード構造にマッピングの設定を行うためのノードを加えているので、ノード内の値を書き換えることで、画像の割り当てを編集可能です。
方法2:
UV Editor上で面と画像を調整する方法
▼インデックスによるUV Editor操作
下の使用例では、こちらの方法を使って位置合わせをしています。
画像の色味調整
画像を追加しただけだと、
- 画像がオブジェクトの色味となじまない
- 世界観として浮いた色味/明るさ
画像自体を編集するという手もありますが、Blender内部で調節できた方が汎用性が高いので、上で追加していたテクスチャノード「ShaderNodeMix(Mix_RGB)」を用いて見え色を調節しています。
画像そのものの色味を出したい場合は、Factorの値を1.00にします。
- Mix(結合)
- Darken(明るく)
- Liten(暗く)
▼参考
Mix (ミックス)ノード — Blender Manual
オブジェクトに画像を張り付ける例
オブジェクトの特定の面に対して、画像を割り当てる処理の例を以下に示します。
実行例 :
ディレクトリ構造:
root_dir
├── image_name.png // 画像
└── main.py // 実行スクリプト
Python :
# スクリプト名
script_text = bpy.context.space_data.text
# スクリプトのディレクトリを取得
script_dir = os.path.dirname(bpy.path.abspath(script_text.filepath))
def Base_create():
bpy.ops.object.mode_set(mode='OBJECT')
# 立方体を追加
bpy.ops.mesh.primitive_cube_add(
size=1
, location=(0, 0, 1)
, scale=(1,1,1)
)
# 名前設定
bpy.context.object.name = "cube_00"
# ベースマテリアル追加
add_new_material(material_name="MT_cube_00")
# Mode切り替え
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_mode(type='FACE')
# 要素選択
element_select(
element_list=[0]
, select_mode="FACE"
, object_name_list=["cube_00"]
)
# マテリアル追加
add_new_material(material_name="MT_cube_00_Content_00")
# Mode切り替え
bpy.ops.object.mode_set(mode='OBJECT')
# イメージテクスチャ追加
add_image_texture(
material_name="MT_cube_00_Content_00"
, image_path= script_dir + "/image_name.png"
, texture_node_name="TX_Image_00"
, node_location=(-400,300)
)
# テクスチャ追加
add_new_texture(
material_name="MT_cube_00_Content_00"
, texture_name="ShaderNodeMix"
, texture_node_name="Mix_RGB_00"
, node_location=(-150, 600)
, settings=[{"name": "data_type", "value": 'RGBA'}]
)
# ノードのリンク
node_link_func(
material_name="MT_cube_00_Content_00"
, texture_node_name_out="Mix_RGB_00"
, texture_node_name_in="Principled BSDF"
, output_link="Result"
, input_link="Base Color"
)
# ノードのリンク
node_link_func(
material_name="MT_cube_00_Content_00"
, texture_node_name_out="TX_Image_00"
, texture_node_name_in="Mix_RGB_00"
, output_link="Color"
, input_link="B"
)
# テクスチャ追加
add_new_texture(
material_name="MT_cube_00_Content_00"
, texture_name="ShaderNodeMapping"
, texture_node_name="Mapping_00"
, node_location=(-600, 300)
)
# ノードのリンク
node_link_func(
material_name="MT_cube_00_Content_00"
, texture_node_name_out="Mapping_00"
, texture_node_name_in="TX_Image_00"
, output_link="Vector"
, input_link="Vector"
)
# テクスチャ追加
add_new_texture(
material_name="MT_cube_00_Content_00"
, texture_name="ShaderNodeTexCoord"
, texture_node_name="TX_Coord_00"
, node_location=(-800, 300)
)
# ノードのリンク
node_link_func(
material_name="MT_cube_00_Content_00"
, texture_node_name_out="TX_Coord_00"
, texture_node_name_in="Mapping_00"
, output_link="UV"
, input_link="Vector"
)
# Mode切り替え
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_mode(type='FACE')
# ------------------------------
# マテリアル 画像の位置合わせ
# ------------------------------
# UV Editor 要素選択
uv_editor_element_select(
element_list=[0]
, select_mode="FACE"
, object_name_list=["cube_00"]
)
# UV Editor 移動
move_selected_uvs(offset_x=0,offset_y=0.38)
# UV Editor 拡大・縮小
common_var=4
scale_selected_uvs(scale_x=common_var, scale_y=common_var)
# UV Editor 回転
rotate_selected_uvs(angle_degrees=-90)
# Mirror 投影
mirror_selected_uvs_x()
# ------------------------------
# マテリアル 画像をマテリアル色になじませる
# ------------------------------
# ノード 値変更
node_value_change(
material_name="MT_cube_00_Content_00"
, node_name="Mix_RGB_00"
, element_name="A"
, set_value=(
0 # red
, 0 # green
, 0 # blue
, 1 # alpha
)
)
# ノード 値変更
node_value_change(
material_name="MT_cube_00_Content_00"
, node_name="Mix_RGB_00"
, element_name="Factor"
, set_value=1
)
Base_create()
特定の面に限定して画像テクスチャを割り当てる場合、
- 全面にオブジェクトのベースとなるマテリアルを追加
- べースマテリアルを上書きする形で、特定の面を選択し画像を適用するマテリアルを追加
▼add_new_material
以上