Upiecz mapę tekstur za pomocą Pythona
Używam Blendera 2.83. Dla dodatku (dostępnego z widoku 3D) chcę wypalić mapy tekstur. Jestem w stanie to zrobić bez skryptów. Ale z Pythonem nie odniosłem sukcesu.
Aby zredukować mój problem do minimum, zacznę od wybranego obiektu z prawidłowym UV. Następnie wykonuję następujący skrypt w języku 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)
Myślę, że to, czego mi brakuje, to poprawne połączenie obrazu z węzłem tekstury. Poradziłem się podobnych pytań, takich jak
Ustaw aktywny węzeł obrazu za pomocą Pythona
ale ich odpowiedzi nie pomogły (myślę, że kod dla Blendera 2.7, który nie jest już kompatybilny).
Odpowiedzi
Myślę, że dam ci kilka podstawowych kroków, to znaczy dodaj węzeł typu „TEX_IMAGE”, przypisz do niego swój obraz. w związku z tym:
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)
Unikaj jak najwięcej używania bpy.ops, w tym przypadku, jak widzisz, łatwo jest stworzyć obraz metodami bpy.data.images.new () Za pomocą tej metody można stworzyć dowolny obiekt blendera.
bpy.data.objects.new()
bpy.data.materials.new()
bpy.data.scenes.new()
...
...
bpy.ops dobrze jest go używać tylko wtedy, gdy nie masz alternatywy, jak w tym przypadku z bpy.ops.object.bake()
pozwala to na stworzenie czegoś i przypisanie tego bezpośrednio do zmiennej, tak jak w przykładzie img = bpy.data.images.new()
Więc nie musisz zwariować, aby mieć do niej dostęp.