Pythonでテクスチャマップをベイクします
私はBlender2.83を使用しています。アドオン(3D-Viewからアクセス可能)の場合、テクスチャマップをベイク処理したいと思います。私はスクリプトなしでそれを完全に行うことができます。しかし、Pythonでは私は成功しませんでした。
問題を最小限に抑えるために、有効なUVを持つ選択されたオブジェクトから始めます。次に、次のPythonスクリプトを実行します。
import bpy
obj = bpy.context.active_object
# Creating a texture node, linked with a new image
mat = obj.data.materials[0]
mat.use_nodes = True
texImage = mat.node_tree.nodes.new('ShaderNodeTexImage')
img = bpy.ops.image.new(name= obj.name + '_BakedTexture')
texImage = img
# !!! No image is linked to the texture node !!!
# Baking to the newly created image
# The following part works if I create the texture node and the assigning of the image by hand
bpy.context.view_layer.objects.active = obj
bpy.ops.object.bake(type='DIFFUSE', save_mode='EXTERNAL', filepath='C:\\TEMP\\baked.png', use_automatic_name=True, width=512, height=512)
私が見逃しているのは、画像とテクスチャノードの正しいリンクだと思います。私は次のような同様の質問を参考にしました
Pythonでアクティブな画像ノードを設定する
しかし、彼らの答えは役に立ちませんでした(互換性がなくなったBlender 2.7のコードだと思います)。
回答
3 NoobCat
基本的な手順をいくつか紹介します。つまり、「TEX_IMAGE」タイプのノードを追加し、それに画像を割り当てます。したがって:
obj = bpy.context.active_object
# You can choose your texture size (This will be the de bake image)
image_name = obj.name + '_BakedTexture'
img = bpy.data.images.new(image_name,1024,1024)
#Due to the presence of any multiple materials, it seems necessary to iterate on all the materials, and assign them a node + the image to bake.
for mat in obj.data.materials:
mat.use_nodes = True #Here it is assumed that the materials have been created with nodes, otherwise it would not be possible to assign a node for the Bake, so this step is a bit useless
nodes = mat.node_tree.nodes
texture_node =nodes.new('ShaderNodeTexImage')
texture_node.name = 'Bake_node'
texture_node.select = True
nodes.active = texture_node
texture_node.image = img #Assign the image to the node
bpy.context.view_layer.objects.active = obj
bpy.ops.object.bake(type='DIFFUSE', save_mode='EXTERNAL')
img.save_render(filepath='C:\\TEMP\\baked.png')
#In the last step, we are going to delete the nodes we created earlier
for mat in obj.data.materials:
for n in mat.node_tree.nodes:
if n.name == 'Bake_node':
mat.node_tree.nodes.remove(n)
bpy.opsの使用はできるだけ避けてください。この場合、ご覧のとおり、bpy.data.images.new()メソッドを使用して画像を簡単に作成できます。このメソッドを使用して任意のBlenderオブジェクトを作成できます。
bpy.data.objects.new()
bpy.data.materials.new()
bpy.data.scenes.new()
...
...
bpy.opsこの場合のように、代替手段がない場合にのみ使用することをお勧めします。 bpy.ops.object.bake()
これにより、次の例のように、何かを作成して変数に直接割り当てることimg = bpy.data.images.new()
ができます。そのため、アクセスするために夢中になる必要はありません。