diff options
author | Lukas Stockner <lukasstockner97> | 2019-12-04 21:57:28 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-12-10 22:44:46 +0300 |
commit | e760972221e68d3c81f2ee3687cc71836dde8ae9 (patch) | |
tree | b1a2efbb17c05a429e4509d336a1eb14c73cfb8c /intern/cycles/blender | |
parent | 35b5888b157d05d378df3acc899d28856a9eb9a4 (diff) |
Cycles: support for custom shader AOVs
Custom render passes are added in the Shader AOVs panel in the view layer
settings, with a name and data type. In shader nodes, an AOV Output node
is then used to output either a value or color to the pass.
Arbitrary names can be used for these passes, as long as they don't conflict
with built-in passes that are enabled. The AOV Output node can be used in both
material and world shader nodes.
Implemented by Lukas, with tweaks by Brecht.
Differential Revision: https://developer.blender.org/D4837
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r-- | intern/cycles/blender/addon/engine.py | 124 | ||||
-rw-r--r-- | intern/cycles/blender/addon/operators.py | 32 | ||||
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 38 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 38 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 17 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 31 |
7 files changed, 220 insertions, 66 deletions
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 013d86a560b..ee7ac7737c0 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -223,65 +223,95 @@ def system_info(): import _cycles return _cycles.system_info() - -def register_passes(engine, scene, srl): - engine.register_pass(scene, srl, "Combined", 4, "RGBA", 'COLOR') - - if srl.use_pass_z: engine.register_pass(scene, srl, "Depth", 1, "Z", 'VALUE') - if srl.use_pass_mist: engine.register_pass(scene, srl, "Mist", 1, "Z", 'VALUE') - if srl.use_pass_normal: engine.register_pass(scene, srl, "Normal", 3, "XYZ", 'VECTOR') - if srl.use_pass_vector: engine.register_pass(scene, srl, "Vector", 4, "XYZW", 'VECTOR') - if srl.use_pass_uv: engine.register_pass(scene, srl, "UV", 3, "UVA", 'VECTOR') - if srl.use_pass_object_index: engine.register_pass(scene, srl, "IndexOB", 1, "X", 'VALUE') - if srl.use_pass_material_index: engine.register_pass(scene, srl, "IndexMA", 1, "X", 'VALUE') - if srl.use_pass_shadow: engine.register_pass(scene, srl, "Shadow", 3, "RGB", 'COLOR') - if srl.use_pass_ambient_occlusion: engine.register_pass(scene, srl, "AO", 3, "RGB", 'COLOR') - if srl.use_pass_diffuse_direct: engine.register_pass(scene, srl, "DiffDir", 3, "RGB", 'COLOR') - if srl.use_pass_diffuse_indirect: engine.register_pass(scene, srl, "DiffInd", 3, "RGB", 'COLOR') - if srl.use_pass_diffuse_color: engine.register_pass(scene, srl, "DiffCol", 3, "RGB", 'COLOR') - if srl.use_pass_glossy_direct: engine.register_pass(scene, srl, "GlossDir", 3, "RGB", 'COLOR') - if srl.use_pass_glossy_indirect: engine.register_pass(scene, srl, "GlossInd", 3, "RGB", 'COLOR') - if srl.use_pass_glossy_color: engine.register_pass(scene, srl, "GlossCol", 3, "RGB", 'COLOR') - if srl.use_pass_transmission_direct: engine.register_pass(scene, srl, "TransDir", 3, "RGB", 'COLOR') - if srl.use_pass_transmission_indirect: engine.register_pass(scene, srl, "TransInd", 3, "RGB", 'COLOR') - if srl.use_pass_transmission_color: engine.register_pass(scene, srl, "TransCol", 3, "RGB", 'COLOR') - if srl.use_pass_subsurface_direct: engine.register_pass(scene, srl, "SubsurfaceDir", 3, "RGB", 'COLOR') - if srl.use_pass_subsurface_indirect: engine.register_pass(scene, srl, "SubsurfaceInd", 3, "RGB", 'COLOR') - if srl.use_pass_subsurface_color: engine.register_pass(scene, srl, "SubsurfaceCol", 3, "RGB", 'COLOR') - if srl.use_pass_emit: engine.register_pass(scene, srl, "Emit", 3, "RGB", 'COLOR') - if srl.use_pass_environment: engine.register_pass(scene, srl, "Env", 3, "RGB", 'COLOR') - +def list_render_passes(srl): + # Builtin Blender passes. + yield ("Combined", "RGBA", 'COLOR') + + if srl.use_pass_z: yield ("Depth", "Z", 'VALUE') + if srl.use_pass_mist: yield ("Mist", "Z", 'VALUE') + if srl.use_pass_normal: yield ("Normal", "XYZ", 'VECTOR') + if srl.use_pass_vector: yield ("Vector", "XYZW", 'VECTOR') + if srl.use_pass_uv: yield ("UV", "UVA", 'VECTOR') + if srl.use_pass_object_index: yield ("IndexOB", "X", 'VALUE') + if srl.use_pass_material_index: yield ("IndexMA", "X", 'VALUE') + if srl.use_pass_shadow: yield ("Shadow", "RGB", 'COLOR') + if srl.use_pass_ambient_occlusion: yield ("AO", "RGB", 'COLOR') + if srl.use_pass_diffuse_direct: yield ("DiffDir", "RGB", 'COLOR') + if srl.use_pass_diffuse_indirect: yield ("DiffInd", "RGB", 'COLOR') + if srl.use_pass_diffuse_color: yield ("DiffCol", "RGB", 'COLOR') + if srl.use_pass_glossy_direct: yield ("GlossDir", "RGB", 'COLOR') + if srl.use_pass_glossy_indirect: yield ("GlossInd", "RGB", 'COLOR') + if srl.use_pass_glossy_color: yield ("GlossCol", "RGB", 'COLOR') + if srl.use_pass_transmission_direct: yield ("TransDir", "RGB", 'COLOR') + if srl.use_pass_transmission_indirect: yield ("TransInd", "RGB", 'COLOR') + if srl.use_pass_transmission_color: yield ("TransCol", "RGB", 'COLOR') + if srl.use_pass_subsurface_direct: yield ("SubsurfaceDir", "RGB", 'COLOR') + if srl.use_pass_subsurface_indirect: yield ("SubsurfaceInd", "RGB", 'COLOR') + if srl.use_pass_subsurface_color: yield ("SubsurfaceCol", "RGB", 'COLOR') + if srl.use_pass_emit: yield ("Emit", "RGB", 'COLOR') + if srl.use_pass_environment: yield ("Env", "RGB", 'COLOR') + + # Cycles specific passes. crl = srl.cycles - if crl.pass_debug_render_time: engine.register_pass(scene, srl, "Debug Render Time", 1, "X", 'VALUE') - if crl.pass_debug_bvh_traversed_nodes: engine.register_pass(scene, srl, "Debug BVH Traversed Nodes", 1, "X", 'VALUE') - if crl.pass_debug_bvh_traversed_instances: engine.register_pass(scene, srl, "Debug BVH Traversed Instances", 1, "X", 'VALUE') - if crl.pass_debug_bvh_intersections: engine.register_pass(scene, srl, "Debug BVH Intersections", 1, "X", 'VALUE') - if crl.pass_debug_ray_bounces: engine.register_pass(scene, srl, "Debug Ray Bounces", 1, "X", 'VALUE') - if crl.use_pass_volume_direct: engine.register_pass(scene, srl, "VolumeDir", 3, "RGB", 'COLOR') - if crl.use_pass_volume_indirect: engine.register_pass(scene, srl, "VolumeInd", 3, "RGB", 'COLOR') - + if crl.pass_debug_render_time: yield ("Debug Render Time", "X", 'VALUE') + if crl.pass_debug_bvh_traversed_nodes: yield ("Debug BVH Traversed Nodes", "X", 'VALUE') + if crl.pass_debug_bvh_traversed_instances: yield ("Debug BVH Traversed Instances", "X", 'VALUE') + if crl.pass_debug_bvh_intersections: yield ("Debug BVH Intersections", "X", 'VALUE') + if crl.pass_debug_ray_bounces: yield ("Debug Ray Bounces", "X", 'VALUE') + if crl.use_pass_volume_direct: yield ("VolumeDir", "RGB", 'COLOR') + if crl.use_pass_volume_indirect: yield ("VolumeInd", "RGB", 'COLOR') + + # Cryptomatte passes. if crl.use_pass_crypto_object: for i in range(0, crl.pass_crypto_depth, 2): - engine.register_pass(scene, srl, "CryptoObject" + '{:02d}'.format(i//2), 4, "RGBA", 'COLOR') + yield ("CryptoObject" + '{:02d}'.format(i//2), "RGBA", 'COLOR') if crl.use_pass_crypto_material: for i in range(0, crl.pass_crypto_depth, 2): - engine.register_pass(scene, srl, "CryptoMaterial" + '{:02d}'.format(i//2), 4, "RGBA", 'COLOR') + yield ("CryptoMaterial" + '{:02d}'.format(i//2), "RGBA", 'COLOR') if srl.cycles.use_pass_crypto_asset: for i in range(0, srl.cycles.pass_crypto_depth, 2): - engine.register_pass(scene, srl, "CryptoAsset" + '{:02d}'.format(i//2), 4, "RGBA", 'COLOR') + yield ("CryptoAsset" + '{:02d}'.format(i//2), "RGBA", 'COLOR') + # Denoising passes. if crl.use_denoising or crl.denoising_store_passes: - engine.register_pass(scene, srl, "Noisy Image", 4, "RGBA", 'COLOR') + yield ("Noisy Image", "RGBA", 'COLOR') if crl.denoising_store_passes: - engine.register_pass(scene, srl, "Denoising Normal", 3, "XYZ", 'VECTOR') - engine.register_pass(scene, srl, "Denoising Albedo", 3, "RGB", 'COLOR') - engine.register_pass(scene, srl, "Denoising Depth", 1, "Z", 'VALUE') - engine.register_pass(scene, srl, "Denoising Shadowing", 1, "X", 'VALUE') - engine.register_pass(scene, srl, "Denoising Variance", 3, "RGB", 'COLOR') - engine.register_pass(scene, srl, "Denoising Intensity", 1, "X", 'VALUE') + yield ("Denoising Normal", "XYZ", 'VECTOR') + yield ("Denoising Albedo", "RGB", 'COLOR') + yield ("Denoising Depth", "Z", 'VALUE') + yield ("Denoising Shadowing", "X", 'VALUE') + yield ("Denoising Variance", "RGB", 'COLOR') + yield ("Denoising Intensity", "X", 'VALUE') clean_options = ("denoising_diffuse_direct", "denoising_diffuse_indirect", "denoising_glossy_direct", "denoising_glossy_indirect", "denoising_transmission_direct", "denoising_transmission_indirect", "denoising_subsurface_direct", "denoising_subsurface_indirect") if any(getattr(crl, option) for option in clean_options): - engine.register_pass(scene, srl, "Denoising Clean", 3, "RGB", 'COLOR') + yield ("Denoising Clean", "RGB", 'COLOR') + + # Custom AOV passes. + for aov in crl.aovs: + if aov.type == 'VALUE': + yield (aov.name, "X", 'VALUE') + else: + yield (aov.name, "RGBA", 'COLOR') + +def register_passes(engine, scene, view_layer): + # Detect duplicate render pass names, first one wins. + listed = set() + for name, channelids, channeltype in list_render_passes(view_layer): + if name not in listed: + engine.register_pass(scene, view_layer, name, len(channelids), channelids, channeltype) + listed.add(name) + +def detect_conflicting_passes(view_layer): + # Detect conflicting render pass names for UI. + counter = {} + for name, _, _ in list_render_passes(view_layer): + counter[name] = counter.get(name, 0) + 1 + + for aov in view_layer.cycles.aovs: + if counter[aov.name] > 1: + aov.conflict = "Conflicts with another render pass with the same name" + else: + aov.conflict = "" diff --git a/intern/cycles/blender/addon/operators.py b/intern/cycles/blender/addon/operators.py index e75d3ab7549..80bb663330b 100644 --- a/intern/cycles/blender/addon/operators.py +++ b/intern/cycles/blender/addon/operators.py @@ -44,6 +44,36 @@ class CYCLES_OT_use_shading_nodes(Operator): return {'FINISHED'} +class CYCLES_OT_add_aov(bpy.types.Operator): + """Add an AOV pass""" + bl_idname="cycles.add_aov" + bl_label="Add AOV" + + def execute(self, context): + view_layer = context.view_layer + cycles_view_layer = view_layer.cycles + + cycles_view_layer.aovs.add() + + view_layer.update_render_passes() + return {'FINISHED'} + + +class CYCLES_OT_remove_aov(bpy.types.Operator): + """Remove an AOV pass""" + bl_idname="cycles.remove_aov" + bl_label="Remove AOV" + + def execute(self, context): + view_layer = context.view_layer + cycles_view_layer = view_layer.cycles + + cycles_view_layer.aovs.remove(cycles_view_layer.active_aov) + + view_layer.update_render_passes() + return {'FINISHED'} + + class CYCLES_OT_denoise_animation(Operator): "Denoise rendered animation sequence using current scene and view " \ "layer settings. Requires denoising data passes and output to " \ @@ -167,6 +197,8 @@ class CYCLES_OT_merge_images(Operator): classes = ( CYCLES_OT_use_shading_nodes, + CYCLES_OT_add_aov, + CYCLES_OT_remove_aov, CYCLES_OT_denoise_animation, CYCLES_OT_merge_images ) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 26e1a6a223a..e09f15b46e8 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -19,6 +19,7 @@ import bpy from bpy.props import ( BoolProperty, + CollectionProperty, EnumProperty, FloatProperty, IntProperty, @@ -31,6 +32,7 @@ from math import pi # enums import _cycles +from . import engine enum_devices = ( ('CPU', "CPU", "Use CPU for rendering"), @@ -190,6 +192,10 @@ enum_view3d_shading_render_pass= ( ('MIST', "Mist", "Show the Mist render pass", 32), ) +enum_aov_types = ( + ('VALUE', "Value", "Write a Value pass", 0), + ('COLOR', "Color", "Write a Color pass", 1), +) class CyclesRenderSettings(bpy.types.PropertyGroup): @@ -1218,8 +1224,29 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): def update_render_passes(self, context): view_layer = context.view_layer view_layer.update_render_passes() + engine.detect_conflicting_passes(view_layer) +class CyclesAOVPass(bpy.types.PropertyGroup): + name: StringProperty( + name="Name", + description="Name of the pass, to use in the AOV Output shader node", + update=update_render_passes, + default="AOV" + ) + type: EnumProperty( + name="Type", + description="Pass data type", + update=update_render_passes, + items=enum_aov_types, + default='COLOR' + ) + conflict: StringProperty( + name="Conflict", + description="If there is a conflict with another render passes, message explaining why", + default="" + ) + class CyclesRenderLayerSettings(bpy.types.PropertyGroup): pass_debug_bvh_traversed_nodes: BoolProperty( @@ -1378,6 +1405,15 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup): update=update_render_passes, ) + aovs: CollectionProperty( + type=CyclesAOVPass, + description="Custom render passes that can be output by shader nodes", + ) + active_aov: IntProperty( + default=0, + min=0 + ) + @classmethod def register(cls): bpy.types.ViewLayer.cycles = PointerProperty( @@ -1552,6 +1588,7 @@ def register(): bpy.utils.register_class(CyclesCurveRenderSettings) bpy.utils.register_class(CyclesDeviceSettings) bpy.utils.register_class(CyclesPreferences) + bpy.utils.register_class(CyclesAOVPass) bpy.utils.register_class(CyclesRenderLayerSettings) bpy.utils.register_class(CyclesView3DShadingSettings) @@ -1573,5 +1610,6 @@ def unregister(): bpy.utils.unregister_class(CyclesCurveRenderSettings) bpy.utils.unregister_class(CyclesDeviceSettings) bpy.utils.unregister_class(CyclesPreferences) + bpy.utils.unregister_class(CyclesAOVPass) bpy.utils.unregister_class(CyclesRenderLayerSettings) bpy.utils.unregister_class(CyclesView3DShadingSettings) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 4ff154d4bcd..011c83d44b8 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -918,6 +918,42 @@ class CYCLES_RENDER_PT_passes_debug(CyclesButtonsPanel, Panel): layout.prop(cycles_view_layer, "pass_debug_ray_bounces") +class CYCLES_RENDER_UL_aov(bpy.types.UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + row = layout.row() + split = row.split(factor=0.65) + icon = 'ERROR' if item.conflict else 'NONE' + split.row().prop(item, "name", text="", icon=icon, emboss=False) + split.row().prop(item, "type", text="", emboss=False) + + +class CYCLES_RENDER_PT_passes_aov(CyclesButtonsPanel, Panel): + bl_label = "Shader AOV" + bl_context = "view_layer" + bl_parent_id = "CYCLES_RENDER_PT_passes" + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + cycles_view_layer = context.view_layer.cycles + + row = layout.row() + col = row.column() + col.template_list("CYCLES_RENDER_UL_aov", "aovs", cycles_view_layer, "aovs", cycles_view_layer, "active_aov", rows=2) + + col = row.column() + sub = col.column(align=True) + sub.operator("cycles.add_aov", icon='ADD', text="") + sub.operator("cycles.remove_aov", icon='REMOVE', text="") + + if cycles_view_layer.active_aov < len(cycles_view_layer.aovs): + active_aov = cycles_view_layer.aovs[cycles_view_layer.active_aov] + if active_aov.conflict: + layout.label(text=active_aov.conflict, icon='ERROR') + + class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel): bl_label = "Denoising" bl_context = "view_layer" @@ -2233,6 +2269,8 @@ classes = ( CYCLES_RENDER_PT_passes_light, CYCLES_RENDER_PT_passes_crypto, CYCLES_RENDER_PT_passes_debug, + CYCLES_RENDER_UL_aov, + CYCLES_RENDER_PT_passes_aov, CYCLES_RENDER_PT_filter, CYCLES_RENDER_PT_override, CYCLES_RENDER_PT_denoising, diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 1f0816a6edb..53f2fdb91b9 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -793,18 +793,13 @@ void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay, for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) { BL::RenderPass b_pass(*b_iter); - - /* find matching pass type */ - PassType pass_type = BlenderSync::get_pass_type(b_pass); int components = b_pass.channels(); - bool read = false; - if (pass_type != PASS_NONE) { - /* copy pixels */ - read = buffers->get_pass_rect( - pass_type, exposure, sample, components, &pixels[0], b_pass.name()); - } - else { + /* Copy pixels from regular render passes. */ + bool read = buffers->get_pass_rect(b_pass.name(), exposure, sample, components, &pixels[0]); + + /* If denoising pass, */ + if (!read) { int denoising_offset = BlenderSync::get_denoising_pass(b_pass); if (denoising_offset >= 0) { read = buffers->get_denoising_pass_rect( @@ -822,7 +817,7 @@ void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay, else { /* copy combined pass */ BL::RenderPass b_combined_pass(b_rlay.passes.find_by_name("Combined", b_rview_name.c_str())); - if (buffers->get_pass_rect(PASS_COMBINED, exposure, sample, 4, &pixels[0], "Combined")) + if (buffers->get_pass_rect("Combined", exposure, sample, 4, &pixels[0])) b_combined_pass.rect(&pixels[0]); } } diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 412e54ea29d..c3564eac940 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -921,6 +921,12 @@ static ShaderNode *add_node(Scene *scene, disp->attribute = ""; node = disp; } + else if (b_node.is_a(&RNA_ShaderNodeOutputAOV)) { + BL::ShaderNodeOutputAOV b_aov_node(b_node); + OutputAOVNode *aov = new OutputAOVNode(); + aov->name = b_aov_node.name(); + node = aov; + } if (node) { node->name = b_node.name(); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index f04455ff75e..bb52c740bfb 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -531,7 +531,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLa if (pass_type == PASS_MOTION && scene->integrator->motion_blur) continue; if (pass_type != PASS_NONE) - Pass::add(pass_type, passes); + Pass::add(pass_type, passes, b_pass.name().c_str()); } PointerRNA crp = RNA_pointer_get(&b_view_layer.ptr, "cycles"); @@ -570,32 +570,32 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLa #ifdef __KERNEL_DEBUG__ if (get_boolean(crp, "pass_debug_bvh_traversed_nodes")) { b_engine.add_pass("Debug BVH Traversed Nodes", 1, "X", b_view_layer.name().c_str()); - Pass::add(PASS_BVH_TRAVERSED_NODES, passes); + Pass::add(PASS_BVH_TRAVERSED_NODES, passes, "Debug BVH Traversed Nodes"); } if (get_boolean(crp, "pass_debug_bvh_traversed_instances")) { b_engine.add_pass("Debug BVH Traversed Instances", 1, "X", b_view_layer.name().c_str()); - Pass::add(PASS_BVH_TRAVERSED_INSTANCES, passes); + Pass::add(PASS_BVH_TRAVERSED_INSTANCES, passes, "Debug BVH Traversed Instances"); } if (get_boolean(crp, "pass_debug_bvh_intersections")) { b_engine.add_pass("Debug BVH Intersections", 1, "X", b_view_layer.name().c_str()); - Pass::add(PASS_BVH_INTERSECTIONS, passes); + Pass::add(PASS_BVH_INTERSECTIONS, passes, "Debug BVH Intersections"); } if (get_boolean(crp, "pass_debug_ray_bounces")) { b_engine.add_pass("Debug Ray Bounces", 1, "X", b_view_layer.name().c_str()); - Pass::add(PASS_RAY_BOUNCES, passes); + Pass::add(PASS_RAY_BOUNCES, passes, "Debug Ray Bounces"); } #endif if (get_boolean(crp, "pass_debug_render_time")) { b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str()); - Pass::add(PASS_RENDER_TIME, passes); + Pass::add(PASS_RENDER_TIME, passes, "Debug Render Time"); } if (get_boolean(crp, "use_pass_volume_direct")) { b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str()); - Pass::add(PASS_VOLUME_DIRECT, passes); + Pass::add(PASS_VOLUME_DIRECT, passes, "VolumeDir"); } if (get_boolean(crp, "use_pass_volume_indirect")) { b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str()); - Pass::add(PASS_VOLUME_INDIRECT, passes); + Pass::add(PASS_VOLUME_INDIRECT, passes, "VolumeInd"); } /* Cryptomatte stores two ID/weight pairs per RGBA layer. @@ -635,6 +635,21 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLa CRYPT_ACCURATE); } + RNA_BEGIN (&crp, b_aov, "aovs") { + bool is_color = (get_enum(b_aov, "type") == 1); + string name = get_string(b_aov, "name"); + + if (is_color) { + b_engine.add_pass(name.c_str(), 4, "RGBA", b_view_layer.name().c_str()); + Pass::add(PASS_AOV_COLOR, passes, name.c_str()); + } + else { + b_engine.add_pass(name.c_str(), 1, "X", b_view_layer.name().c_str()); + Pass::add(PASS_AOV_VALUE, passes, name.c_str()); + } + } + RNA_END; + return passes; } |