Cycles: Use Blender Settings For AOV

This patch will share the AOV settings between Cycles and Eevee.
It enable using the AOV name conflict detection of Blender. This
means that unlike how Cycles used to work it isn't possible to add an
AOV with a similar name. Conflicts with internal render pass names will
be indicated with an Warning icon.

Reviewed By: Brecht van Lommel

Differential Revision: https://developer.blender.org/D9774
This commit is contained in:
Jeroen Bakker 2021-02-12 11:29:50 +01:00
parent 837b5743ce
commit 26481eabe1
Notes: blender-bot 2023-02-14 09:29:42 +01:00
Referenced by issue #81094, EEVEE: AOVs
13 changed files with 70 additions and 155 deletions

View File

@ -301,7 +301,7 @@ def list_render_passes(scene, srl):
yield ("Denoising Clean", "RGB", 'COLOR')
# Custom AOV passes.
for aov in crl.aovs:
for aov in srl.aovs:
if aov.type == 'VALUE':
yield (aov.name, "X", 'VALUE')
else:
@ -309,22 +309,5 @@ def list_render_passes(scene, srl):
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(scene, 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(scene, view_layer):
# Detect conflicting render pass names for UI.
counter = {}
for name, _, _ in list_render_passes(scene, 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 = ""
engine.register_pass(scene, view_layer, name, len(channelids), channelids, channeltype)

View File

@ -44,36 +44,6 @@ 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 " \
@ -197,8 +167,6 @@ 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
)

View File

@ -178,11 +178,6 @@ 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),
)
def enum_openimagedenoise_denoiser(self, context):
import _cycles
@ -229,7 +224,6 @@ def update_render_passes(self, context):
scene = context.scene
view_layer = context.view_layer
view_layer.update_render_passes()
engine.detect_conflicting_passes(scene, view_layer)
class CyclesRenderSettings(bpy.types.PropertyGroup):
@ -1311,27 +1305,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
del bpy.types.Scene.cycles_curves
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(
@ -1470,15 +1443,6 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
default='RGB_ALBEDO_NORMAL',
)
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(
@ -1665,7 +1629,6 @@ 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)
@ -1687,6 +1650,5 @@ 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)

View File

@ -23,7 +23,7 @@ from bl_ui.utils import PresetPanel
from bpy.types import Panel
from bl_ui.properties_grease_pencil_common import GreasePencilSimplifyPanel
from bl_ui.properties_view_layer import ViewLayerCryptomattePanel
from bl_ui.properties_view_layer import ViewLayerCryptomattePanel, ViewLayerAOVPanel
class CYCLES_PT_sampling_presets(PresetPanel, Panel):
@ -915,49 +915,11 @@ 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):
class CYCLES_RENDER_PT_passes_aov(CyclesButtonsPanel, ViewLayerAOVPanel):
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"
@ -2300,7 +2262,6 @@ 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,

View File

@ -108,7 +108,7 @@ def do_versions(self):
library_versions.setdefault(library.version, []).append(library)
# Do versioning per library, since they might have different versions.
max_need_versioning = (2, 92, 4)
max_need_versioning = (2, 92, 14)
for version, libraries in library_versions.items():
if version > max_need_versioning:
continue
@ -204,6 +204,18 @@ def do_versions(self):
view_layer.pass_cryptomatte_depth = cview_layer.get("pass_crypto_depth", 6)
view_layer.use_pass_cryptomatte_accurate = cview_layer.get("pass_crypto_accurate", True)
if version <= (2, 92, 14):
if scene.render.engine == 'CYCLES':
for view_layer in scene.view_layers:
cview_layer = view_layer.cycles
for caov in cview_layer.get("aovs", []):
aov_name = caov.get("name", "AOV")
if aov_name in view_layer.aovs:
continue
baov = view_layer.aovs.add()
baov.name = caov.get("name", "AOV")
baov.type = "COLOR" if caov.get("type", 1) == 1 else "VALUE"
# Lamps
for light in bpy.data.lights:
if light.library not in libraries:

View File

@ -706,9 +706,15 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
}
}
RNA_BEGIN (&crl, b_aov, "aovs") {
bool is_color = (get_enum(b_aov, "type") == 1);
string name = get_string(b_aov, "name");
BL::ViewLayer::aovs_iterator b_aov_iter;
for (b_view_layer.aovs.begin(b_aov_iter); b_aov_iter != b_view_layer.aovs.end(); ++b_aov_iter) {
BL::AOV b_aov(*b_aov_iter);
if (!b_aov.is_valid()) {
continue;
}
string name = b_aov.name();
bool is_color = b_aov.type() == BL::AOV::type_COLOR;
if (is_color) {
b_engine.add_pass(name.c_str(), 4, "RGBA", b_view_layer.name().c_str());
@ -719,7 +725,6 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
Pass::add(PASS_AOV_VALUE, passes, name.c_str());
}
}
RNA_END;
scene->film->set_denoising_data_pass(denoising.use || denoising.store_passes);
scene->film->set_denoising_clean_pass(scene->film->get_denoising_flags() &

View File

@ -143,10 +143,8 @@ class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel):
col.active = scene_eevee.use_bloom
class VIEWLAYER_PT_layer_passes_aov(ViewLayerButtonsPanel, Panel):
class ViewLayerAOVPanel(ViewLayerButtonsPanel, Panel):
bl_label = "Shader AOV"
bl_parent_id = "VIEWLAYER_PT_layer_passes"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
def draw(self, context):
layout = self.layout
@ -170,6 +168,11 @@ class VIEWLAYER_PT_layer_passes_aov(ViewLayerButtonsPanel, Panel):
layout.label(text="Conflicts with another render pass with the same name", icon='ERROR')
class VIEWLAYER_PT_layer_passes_aov(ViewLayerAOVPanel):
bl_parent_id = "VIEWLAYER_PT_layer_passes"
COMPAT_ENGINES = {'BLENDER_EEVEE'}
class ViewLayerCryptomattePanel(ViewLayerButtonsPanel, Panel):
bl_label = "Cryptomatte"

View File

@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 14
#define BLENDER_FILE_SUBVERSION 15
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file

View File

@ -1590,18 +1590,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
FOREACH_NODETREE_END;
}
/**
* Versioning code until next subversion bump goes here.
*
* \note Be sure to check when bumping the version:
* - "versioning_userdef.c", #blo_do_versions_userdef
* - "versioning_userdef.c", #do_versions_theme
*
* \note Keep this message at the bottom of the function.
*/
{
/* Keep this block, even when empty. */
if (!MAIN_VERSION_ATLEAST(bmain, 292, 15)) {
/* UV/Image Max resolution images in image editor. */
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
@ -1614,4 +1603,17 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
/**
* Versioning code until next subversion bump goes here.
*
* \note Be sure to check when bumping the version:
* - "versioning_userdef.c", #blo_do_versions_userdef
* - "versioning_userdef.c", #do_versions_theme
*
* \note Keep this message at the bottom of the function.
*/
{
/* Keep this block, even when empty. */
}
}

View File

@ -264,7 +264,7 @@ void rna_def_mtex_common(struct BlenderRNA *brna,
const char *update,
const char *update_index);
void rna_def_texpaint_slots(struct BlenderRNA *brna, struct StructRNA *srna);
void rna_def_view_layer_common(struct StructRNA *srna, const bool scene);
void rna_def_view_layer_common(struct BlenderRNA *brna, struct StructRNA *srna, const bool scene);
void rna_def_actionbone_group_common(struct StructRNA *srna,
int update_flag,

View File

@ -534,7 +534,7 @@ void RNA_def_view_layer(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_ViewLayer_path");
RNA_def_struct_idprops_func(srna, "rna_ViewLayer_idprops");
rna_def_view_layer_common(srna, true);
rna_def_view_layer_common(brna, srna, true);
func = RNA_def_function(srna, "update_render_passes", "rna_ViewLayer_update_render_passes");
RNA_def_function_ui_description(func,

View File

@ -1050,7 +1050,7 @@ static void rna_def_render_layer(BlenderRNA *brna)
RNA_define_verify_sdna(0);
rna_def_view_layer_common(srna, false);
rna_def_view_layer_common(brna, srna, false);
prop = RNA_def_property(srna, "passes", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "RenderPass");

View File

@ -4062,6 +4062,24 @@ static void rna_def_view_layer_eevee(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
}
static void rna_def_view_layer_aovs(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
/* PropertyRNA *prop; */
FunctionRNA *func;
PropertyRNA *parm;
RNA_def_property_srna(cprop, "AOVs");
srna = RNA_def_struct(brna, "AOVs", NULL);
RNA_def_struct_sdna(srna, "ViewLayer");
RNA_def_struct_ui_text(srna, "List of AOVs", "Collection of AOVs");
func = RNA_def_function(srna, "add", "BKE_view_layer_add_aov");
parm = RNA_def_pointer(func, "aov", "AOV", "", "Newly created AOV");
RNA_def_function_return(func, parm);
}
static void rna_def_view_layer_aov(BlenderRNA *brna)
{
StructRNA *srna;
@ -4089,7 +4107,7 @@ static void rna_def_view_layer_aov(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
}
void rna_def_view_layer_common(StructRNA *srna, const bool scene)
void rna_def_view_layer_common(BlenderRNA *brna, StructRNA *srna, const bool scene)
{
PropertyRNA *prop;
@ -4144,6 +4162,7 @@ void rna_def_view_layer_common(StructRNA *srna, const bool scene)
RNA_def_property_collection_sdna(prop, NULL, "aovs", NULL);
RNA_def_property_struct_type(prop, "AOV");
RNA_def_property_ui_text(prop, "Shader AOV", "");
rna_def_view_layer_aovs(brna, prop);
prop = RNA_def_property(srna, "active_aov", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "AOV");