Bagaimana cara memutar file EXR Multilayer di kompositor Blender?

Nov 18 2020

Tampaknya memutar gambar adalah tugas yang sepele, namun saya menghadapi masalah ini saat bekerja dengan file format EXR Multilayer di Blender.

Tapi kenapa?

Saya merasa nyaman untuk mengatur adegan archvis saya sebagai animasi sehingga saya dapat mengubah objek dalam berbagai gambar diam dan merender semua sudut kamera sekaligus sebagai animasi. Saya terkadang memerlukan gambar orientasi lanskap dan potret dari interior yang sama dan menggunakan skrip kecil untuk dengan cepat mengganti dimensi resolusi X dan Y, lalu memutar kamera setelah selesai membingkai sehingga beberapa bingkai ditampilkan diputar. Maka sangat mudah bagi saya untuk melakukan pengomposisian pada urutan gambar.

Baru-baru ini saya membuat pemandangan dalam beberapa batch dan berakhir dengan 1 gambar panorama 8K, 5 gambar ruang keluarga 4K dalam orientasi lanskap dengan salah satunya diputar dan 5 gambar tangga yang semuanya berorientasi potret semuanya dalam urutan dan saya terkejut ketika pengomposisian Saya dapat melakukannya dengan semua gambar sekaligus sebagai satu urutan meskipun ada perbedaan dalam orientasi dan resolusi dan mengeluarkannya ke file dengan node Output File ke resolusi dan orientasi yang benar dari satu urutan itu. Jadi sekarang saya tahu, saya bisa memiliki orientasi berbeda dalam urutan yang sama yaitu amasing.

Akan lebih menakjubkan jika saya selalu dapat melihat semua gambar yang diputar dengan benar saat mengomposisikan alih-alih hanya memutar output seperti yang telah saya lakukan hingga sekarang.

Ini akan mengharuskan saya untuk memutar semua file EXR Multilayer yang diberikan yang memerlukan rotasi dalam urutan file saya.

Apa yang telah saya coba

Saya tidak memiliki masalah menghubungkan setiap output dari Multilayer EXR ke node Output File dengan Python dan juga memasukkan node Compositor untuk mengeditnya secara otomatis sehingga solusi apa pun yang berfungsi untuk satu lapisan nyaman bagi saya, namun saya tidak dapat memutar gambar dalam kompositor sejauh ini. karena gambar dipotong ke dimensi aslinya saat diputar:

Pertanyaan

Apakah mungkin untuk memutar setiap lapisan EXR Multilayer dan menampilkannya ke gambar dengan dimensi yang diputar juga dengan node Compositor Blender, jika - bagaimana?

Solusi saya yang dirinci dan jawaban di bawah ini bermasalah dengan Cryptomatte. Saya memulai hadiah dengan harapan menemukan solusi tanpa masalah itu. Saya mulai memikirkan solusi dengan Python, tetapi tidak tahu bagaimana itu akan sederhana dan mudah digunakan dari Blender ...

Jawaban

3 lemon Dec 09 2020 at 22:26

Tentang cryptomatt

Masalahnya bukan karena rotasi tetapi pada node alfa di atas:

yang menghasilkan gambar berwarna polos.

Jika Anda mengubah grup node dengan ini:

Itu memungkinkan untuk menjaga ukuran gambar dari topeng, tanpa mempertimbangkannya (dikalikan dengan 0) tetapi menambahkan nilai cryptomatte yang diputar.

File kasus uji sederhana:

2 MartynasŽiemys Nov 19 2020 at 17:05

Solusi ini memiliki masalah - lihat akhir jawabannya.

Seperti yang ditunjukkan oleh brockmann, ada pertanyaan yang sangat mirip tentang memutar gambar yang gagal saya temukan. Ini semacam menjelaskan bahwa dimensi gambar dalam kompositor diwarisi dari node pertama jika dicampur dengan sesuatu. Simpul topeng tanpa topeng apa pun yang dipilih berfungsi untuk mengatur dimensi dengan sempurna:

Jadi untuk memutar file EXR Multilayer seseorang perlu memutar semua layer dan dengan Python yang di dalam addon kecil membuat panel akan terlihat seperti ini:

bl_info = {
    "name": "Nodes",
    "author": "Martynas Žiemys",
    "version": (1, 0),
    "blender": (2, 80, 0),
    "location": "Compositor -> n panel -> Node Tools",
    "description": "",
    "warning": "",
    "doc_url": "",
    "category": "Compositor",
}

import bpy
from bpy.types import Panel, Operator
from mathutils import Vector
from math import radians

class OutputRotatedMultilayer(Operator):
    """Make multilayer EXR file output for all outputs of active image node rotated"""
    bl_idname = "node.multilayer_output_rotated"
    bl_label = "Multilayer Output Rotated"

    @classmethod
    def poll(cls, context):
        image_node_active = False
        if context.scene.node_tree.nodes.active is not None:
            image_node_active = (context.scene.node_tree.nodes.active.type in {"IMAGE","R_LAYERS"})
        return image_node_active

    def execute(self, context):
        if "RotateImage" not in bpy.data.node_groups:
            rotate = bpy.data.node_groups.new('RotateImage', 'CompositorNodeTree')
            rotate.inputs.new('NodeSocketColor','Image')
            rotate.outputs.new('NodeSocketColor','Image')
            out = rotate.nodes.new('NodeGroupOutput')
            out.location = (200,0)
            input = rotate.nodes.new('NodeGroupInput')
            input.location = (-400,0)
            mask = rotate.nodes.new('CompositorNodeMask')
            mask.location = (-200,200)
            mask.use_feather = 0
            mask.size_source = 'FIXED'
            mask.size_x = 3600
            mask.size_y = 2400
            mix = rotate.nodes.new('CompositorNodeAlphaOver')
            mix.location = (0,25)
            mix.hide = 1
            rot = rotate.nodes.new('CompositorNodeRotate')
            rot.location = (-200,-50)
            rot.filter_type = 'NEAREST'
            rot.inputs[1].default_value= radians(90)
            rotate.links.new(out.inputs[0], mix.outputs[0])
            rotate.links.new(rot.inputs[0], input.outputs[0])
            rotate.links.new(mix.inputs[1], mask.outputs[0])
            rotate.links.new(mix.inputs[2], rot.outputs[0])
            
        width = context.scene.node_tree.nodes.active.width
        active = context.scene.node_tree.nodes.active
        tree = context.scene.node_tree
        links = tree.links 
        output = tree.nodes.new('CompositorNodeOutputFile')  
        output.location = active.location + Vector((500,0))
        output.format.file_format = 'OPEN_EXR_MULTILAYER'
        output.format.color_depth = '32'
        output.format.color_mode = 'RGBA'
        output.format.compression = 15
        output.layer_slots.clear()
        for i,every_slot in enumerate(active.outputs):
            if active.type == "R_LAYERS":
                if every_slot.enabled:
                    output.layer_slots.new( name = every_slot.name )
                    g = tree.nodes.new('CompositorNodeGroup')
                    g.node_tree = bpy.data.node_groups["RotateImage"]
                    g.hide = 1 
                    g.location = (-100,i*50)
                    links.new(active.outputs[i], g.inputs[0])
                    links.new(g.outputs[0], output.inputs[every_slot.name])
            else:
                output.layer_slots.new( name = every_slot.name )
                g = tree.nodes.new('CompositorNodeGroup')
                g.node_tree = bpy.data.node_groups["RotateImage"]
                g.hide = 1 
                g.location = active.location + Vector((200,i*-33))
                links.new(active.outputs[i], g.inputs[0])
                links.new(g.outputs[0], output.inputs[every_slot.name])
                
                
        return {'FINISHED'}

class NODE_PT_node_tools(Panel):
    bl_space_type = 'NODE_EDITOR'
    bl_region_type = 'UI'
    bl_category = "Node Tools"
    bl_label = "Node Tools"

    @classmethod
    def poll(cls, context):
        space = context.space_data
        return space.type == 'NODE_EDITOR'

    def draw(self, context):
        layout = self.layout
        col = layout.column()
        col.operator("node.multilayer_output_rotated")
        
def register():
    bpy.utils.register_class(OutputRotatedMultilayer)
    bpy.utils.register_class(NODE_PT_node_tools)


def unregister():
    bpy.utils.unregister_class(OutputRotatedMultilayer)
    bpy.utils.unregister_class(NODE_PT_node_tools)


if __name__ == "__main__":
    register()

Ternyata ini tidak berfungsi untuk Cryptomatte

Proses rotasi mengacaukan presisi nilai Cryptomatte yang menghasilkan tepi topeng yang salah:

1 GordonBrinkmann Nov 18 2020 at 21:55

Karena Hasil Render tidak memperhitungkan dimensi atau orientasi EXR, jawabannya bergantung pada hasil yang ingin Anda capai. Cara sederhananya adalah, jika EXR misalnya 1920 x 1080, atur Render Dimensions ke 1920 x 1920. Dengan cara ini gambar akan selalu pas dan tidak akan dipotong. Jika Anda ingin merender pada persentase yang berbeda seperti mungkin 50%, Anda harus menempatkan Node Skala setelah Rotate Node diatur ke Render Size> Fit .

Jika Anda ingin menjaga rasio aspek gambar yang dirender pada 16: 9, ada dua cara yang bisa dilakukan:

  1. EXR harus mengisi ruang sebanyak mungkin (1920 x 1080 pada 0 °, 608 x 1080 pada 90 °) atau
  2. ukurannya harus tetap sama (1080 x 608 pada 0 °, 608 x 1080 pada 90 °).

Apa pun itu, Anda memerlukan Scale Node yang dijelaskan di atas dengan Render Size> Fit dan Scale Node kedua diatur ke Relative> X = Y = 9/16 = 0.5625 .

Untuk opsi 1 Anda harus menonaktifkan node Relatif atau mengatur X = Y = 1 jika rotasinya 0 °. Untuk 90 ° atau -90 ° Anda harus mengaktifkannya dengan X = Y = 0,5625.

Untuk opsi 2 Anda membiarkannya diaktifkan tidak peduli apakah 0 ° atau 90 °, tetapi seperti yang disebutkan sebelumnya dalam hal ini EXR tidak akan mengisi gambar secara horizontal.

Saya telah membuat pengaturan node dengan penonaktifan otomatis node Relatif sesuai dengan nilai Rotasi, lihat gambar. Idenya adalah jika Anda ingin membuat urutan dan menyetel bingkai utama untuk rotasi, Anda tidak perlu menonaktifkan node secara manual. Rasio aspek Dimensi Render dihitung oleh pengemudi.