Commit: 1a6b48078570e746aab6412a955a8b6b87149e7b Author: Sergey Sharybin Date: Thu Aug 5 15:50:51 2021 +0200 Branches: cycles-x https://developer.blender.org/rB1a6b48078570e746aab6412a955a8b6b87149e7b
Cycles X: More flexible OIDN prefiltering settings Allows to bring back old behavior when color and guiding passes are denoised at the same time. Exposed as a single enum, so that we only expose combinations which makes sense from configuration perspective. Possibilities are: - None. Assumes that the guiding passes are clean. Gives best results without extra processing time (in expense of requiring to have enough samples rendered to give clean guiding passes). Corresponds to OIDN cleanAux=true and no prefiltering done on the guiding passes. - Fast. Old behavior, color and guiiding passes are denoised together. This is fastest way of giving denoised result, in the expense of possible loss of details. Corresponds to OIDN cleanAux=false and no prefiltering. - Accurate. Use special guiding passes prefilteringbefore denoising color passes. Gives best results in the expense of extra time needed to perform prefiltering. Avoids over-blurring details. Corresponds to OIDN cleanAux=true and prefiltering performed on the guiding passes. Differential Revision: https://developer.blender.org/D12140 =================================================================== M intern/cycles/blender/addon/properties.py M intern/cycles/blender/addon/ui.py M intern/cycles/blender/blender_sync.cpp M intern/cycles/device/device_denoise.h M intern/cycles/integrator/denoiser_oidn.cpp M intern/cycles/render/integrator.cpp M intern/cycles/render/integrator.h =================================================================== diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 6a3c439182c..175e6983012 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -205,6 +205,11 @@ enum_denoising_input_passes = ( ('RGB_ALBEDO_NORMAL', "Color + Albedo + Normal", "Use color, albedo and normal data as input", 3), ) +enum_denoising_prefilter = ( + ('NONE', "None", "No prefiltering, use when guiding passes are noise-free", 1), + ('FAST', "Fast", "Denoise color and guiding passes together. Improves quality when guiding passes are noisy using least amount of extra processing time", 2), + ('ACCURATE', "Accurate", "Prefilter noisy guiding passes before denoising color. Improves quality when guiding passes are noisy using extra processing time", 3), +) def update_render_passes(self, context): scene = context.scene @@ -248,10 +253,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Denoise the image in the 3D viewport", default=False, ) - use_preview_denoising_prefilter: BoolProperty( - name="Use Denoising Prefilter", + preview_denoising_prefilter: EnumProperty( + name="Denoising Prefilter", description="Prefilter noisy guiding (albedo and normal) passes to improve denoising quality when using OpenImageDenoiser", - default=False, + items=enum_denoising_prefilter, + default=2, ) denoiser: EnumProperty( @@ -1222,10 +1228,11 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup): items=enum_denoising_input_passes, default='RGB_ALBEDO_NORMAL', ) - use_denoising_prefilter: BoolProperty( - name="Use Denoising Prefilter", + denoising_prefilter: EnumProperty( + name="Denoising Prefilter", description="Prefilter noisy guiding (albedo and normal) passes to improve denoising quality when using OpenImageDenoiser", - default=True, + items=enum_denoising_prefilter, + default=1, ) @classmethod diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index c30deb52bd9..b5b3d08e66d 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -183,7 +183,7 @@ class CYCLES_RENDER_PT_sampling_viewport(CyclesButtonsPanel, Panel): effective_preview_denoiser = get_effective_preview_denoiser(context) if effective_preview_denoiser == 'OPENIMAGEDENOISE': - sub_row.prop(cscene, "use_preview_denoising_prefilter", text="Prefilter") + sub_row.prop(cscene, "preview_denoising_prefilter", text="Prefilter") class CYCLES_RENDER_PT_sampling_render(CyclesButtonsPanel, Panel): @@ -846,7 +846,7 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel): col.prop(cycles_view_layer, "denoising_optix_input_passes") elif denoiser == 'OPENIMAGEDENOISE': col.prop(cycles_view_layer, "denoising_openimagedenoise_input_passes") - col.prop(cycles_view_layer, "use_denoising_prefilter", text="Prefilter") + col.prop(cycles_view_layer, "denoising_prefilter", text="Prefilter") class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel): diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 54cfd90b77c..83aa3c1a79f 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -373,7 +373,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background) integrator->set_denoise_start_sample(denoise_params.start_sample); integrator->set_use_denoise_pass_albedo(denoise_params.use_pass_albedo); integrator->set_use_denoise_pass_normal(denoise_params.use_pass_normal); - integrator->set_use_denoise_prefilter(denoise_params.use_prefilter); + integrator->set_denoiser_prefilter(denoise_params.prefilter); } /* UPDATE_NONE as we don't want to tag the integrator as modified (this was done by the @@ -903,7 +903,8 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene, denoising.store_passes = get_boolean(clayer, "denoising_store_passes"); - denoising.use_prefilter = get_boolean(clayer, "use_denoising_prefilter"); + denoising.prefilter = (DenoiserPrefilter)get_enum( + clayer, "denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_NONE); } } else { @@ -912,11 +913,13 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene, denoising.type = (DenoiserType)get_enum( cscene, "preview_denoiser", DENOISER_NUM, DENOISER_NONE); denoising.start_sample = get_int(cscene, "preview_denoising_start_sample"); - denoising.use_prefilter = get_boolean(cscene, "use_preview_denoising_prefilter"); input_passes = (DenoiserInput)get_enum( cscene, "preview_denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO); + denoising.prefilter = (DenoiserPrefilter)get_enum( + cscene, "preview_denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_FAST); + /* Auto select fastest denoiser. */ if (denoising.type == DENOISER_NONE) { if (!Device::available_devices(DEVICE_MASK_OPTIX).empty()) { diff --git a/intern/cycles/device/device_denoise.h b/intern/cycles/device/device_denoise.h index 5d958fa03bf..78090b4e328 100644 --- a/intern/cycles/device/device_denoise.h +++ b/intern/cycles/device/device_denoise.h @@ -35,6 +35,22 @@ const char *denoiserTypeToHumanReadable(DenoiserType type); typedef int DenoiserTypeMask; +enum DenoiserPrefilter { + /* Best quality of the result without extra processing time, but requires guiding passes to be + * noise-free. */ + DENOISER_PREFILTER_NONE = 1, + + /* Denoise color and guiding passes together. + * Improves quality when guiding passes are noisy using least amount of extra processing time. */ + DENOISER_PREFILTER_FAST = 2, + + /* Prefilter noisy guiding passes before denoising color. + * Improves quality when guiding passes are noisy using extra processing time. */ + DENOISER_PREFILTER_ACCURATE = 3, + + DENOISER_PREFILTER_NUM, +}; + class DenoiseParams { public: /* Apply denoiser to image. */ @@ -55,7 +71,7 @@ class DenoiseParams { bool use_pass_albedo = true; bool use_pass_normal = false; - bool use_prefilter = false; + DenoiserPrefilter prefilter = DENOISER_PREFILTER_FAST; DenoiseParams() = default; @@ -63,7 +79,7 @@ class DenoiseParams { { return !(use == other.use && store_passes == other.store_passes && type == other.type && start_sample == other.start_sample && use_pass_albedo == other.use_pass_albedo && - use_pass_normal == other.use_pass_normal && use_prefilter == other.use_prefilter); + use_pass_normal == other.use_pass_normal && prefilter == other.prefilter); } }; diff --git a/intern/cycles/integrator/denoiser_oidn.cpp b/intern/cycles/integrator/denoiser_oidn.cpp index bf530b2cbc8..2726baaebe8 100644 --- a/intern/cycles/integrator/denoiser_oidn.cpp +++ b/intern/cycles/integrator/denoiser_oidn.cpp @@ -185,7 +185,10 @@ class OIDNDenoiseContext { oidn_filter.setProgressMonitorFunction(oidn_progress_monitor_function, denoiser_); oidn_filter.set("hdr", true); oidn_filter.set("srgb", false); - oidn_filter.set("cleanAux", true); + if (denoise_params_.prefilter == DENOISER_PREFILTER_NONE || + denoise_params_.prefilter == DENOISER_PREFILTER_ACCURATE) { + oidn_filter.set("cleanAux", true); + } oidn_filter.commit(); filter_guiding_pass_if_needed(oidn_device, oidn_albedo_pass_); @@ -206,7 +209,8 @@ class OIDNDenoiseContext { protected: void filter_guiding_pass_if_needed(oidn::DeviceRef &oidn_device, OIDNPass &oidn_pass) { - if (!denoise_params_.use_prefilter || !oidn_pass || oidn_pass.is_filtered) { + if (denoise_params_.prefilter != DENOISER_PREFILTER_ACCURATE || !oidn_pass || + oidn_pass.is_filtered) { return; } @@ -228,7 +232,8 @@ class OIDNDenoiseContext { DCHECK(!oidn_pass.use_compositing); - if (!denoise_params_.use_prefilter && !is_pass_scale_needed(oidn_pass)) { + if (denoise_params_.prefilter != DENOISER_PREFILTER_ACCURATE && + !is_pass_scale_needed(oidn_pass)) { /* Pass data is available as-is from the render buffers. */ return; } diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index 03599ef81f3..d88bab0a4fe 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -85,6 +85,11 @@ NODE_DEFINE(Integrator) denoiser_type_enum.insert("optix", DENOISER_OPTIX); denoiser_type_enum.insert("openimagedenoise", DENOISER_OPENIMAGEDENOISE); + static NodeEnum denoiser_prefilter_enum; + denoiser_prefilter_enum.insert("none", DENOISER_PREFILTER_NONE); + denoiser_prefilter_enum.insert("fast", DENOISER_PREFILTER_FAST); + denoiser_prefilter_enum.insert("accurate", DENOISER_PREFILTER_ACCURATE); + /* Construct default parameters, so that they are the source of truth for defaults. */ const DenoiseParams default_denoise_params; @@ -99,9 +104,10 @@ NODE_DEFINE(Integrator) SOCKET_BOOLEAN(use_denoise_pass_normal, "Use Normal Pass for Denoiser Denoiser", default_denoise_params.use_pass_normal); - SOCKET_BOOLEAN(use_denoise_prefilter, - "Prefilter noisy guiding passes", - default_denoise_params.use_pass_normal); + SOCKET_ENUM(denoiser_prefilter, + "Denoiser Type", + denoiser_prefilter_enum, + default_denoise_params.prefilter); return type; } @@ -310,7 +316,7 @@ DenoiseParams Integrator::get_denoise_params() const denoise_params.use_pass_albedo = use_denoise_pass_albedo; denoise_params.use_pass_normal = use_denoise_pass_normal; - denoise_params.use_prefilter = use_denoise_prefilter; + denoise_params.prefilter = denoiser_prefilter; return denoise_params; } diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h index 7976c29f773..163574ed55 @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
