Nướng bản đồ kết cấu với python

Aug 15 2020

Tôi sử dụng Blender 2.83. Đối với một addon (có thể truy cập từ 3D-View), tôi muốn tạo bản đồ kết cấu. Tôi hoàn toàn có thể làm điều đó mà không cần viết kịch bản. Nhưng với python, tôi đã không thành công.

Để giảm vấn đề của tôi xuống mức tối thiểu nhất, tôi bắt đầu với một đối tượng đã chọn có UV hợp lệ. Sau đó, tôi thực thi tập lệnh python sau:

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)

Tôi nghĩ điều tôi còn thiếu là liên kết chính xác của hình ảnh với nút kết cấu. Tôi đã tham khảo những câu hỏi tương tự như

Đặt nút hình ảnh hoạt động bằng python

nhưng câu trả lời của họ đã không giúp được gì (mã cho Blender 2.7 không tương thích nữa, tôi đoán vậy).

Trả lời

3 NoobCat Aug 22 2020 at 01:23

Tôi nghĩ rằng tôi sẽ cung cấp cho bạn một số bước cơ bản, đó là thêm một nút kiểu "TEX_IMAGE", gán hình ảnh của bạn cho nó. vì thế:

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)

Tránh càng nhiều càng tốt việc sử dụng bpy.ops, trong trường hợp này, như bạn thấy, rất dễ dàng để tạo một hình ảnh bằng phương thức bpy.data.images.new () Bất kỳ đối tượng máy xay sinh tố nào cũng có thể được tạo bằng phương thức đó.

bpy.data.objects.new()
bpy.data.materials.new()
bpy.data.scenes.new()
...
...

bpy.ops chỉ nên sử dụng nó khi bạn không có lựa chọn thay thế nào, như trong trường hợp này với bpy.ops.object.bake()

điều này cho phép bạn tạo một cái gì đó và gán nó trực tiếp cho một biến, như trong ví dụ về img = bpy.data.images.new()Vì vậy, bạn không cần phải điên đầu để có quyền truy cập vào nó.