Cycles: Added quality parameter for OIDN #115265
|
@ -56,6 +56,7 @@ class AddPresetSampling(AddPresetBase, Operator):
|
||||||
"cycles.denoiser",
|
"cycles.denoiser",
|
||||||
"cycles.denoising_input_passes",
|
"cycles.denoising_input_passes",
|
||||||
"cycles.denoising_prefilter",
|
"cycles.denoising_prefilter",
|
||||||
|
"cycles.denoising_quality",
|
||||||
]
|
]
|
||||||
|
|
||||||
preset_subdir = "cycles/sampling"
|
preset_subdir = "cycles/sampling"
|
||||||
|
@ -80,6 +81,7 @@ class AddPresetViewportSampling(AddPresetBase, Operator):
|
||||||
"cycles.preview_denoiser",
|
"cycles.preview_denoiser",
|
||||||
"cycles.preview_denoising_input_passes",
|
"cycles.preview_denoising_input_passes",
|
||||||
"cycles.preview_denoising_prefilter",
|
"cycles.preview_denoising_prefilter",
|
||||||
|
"cycles.preview_denoising_quality",
|
||||||
"cycles.preview_denoising_start_sample",
|
"cycles.preview_denoising_start_sample",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,17 @@ enum_denoising_prefilter = (
|
||||||
3),
|
3),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
enum_denoising_quality = (
|
||||||
|
('HIGH',
|
||||||
|
"High",
|
||||||
|
"High quality",
|
||||||
|
1),
|
||||||
|
('BALANCED',
|
||||||
|
"Balanced",
|
||||||
|
"Balances quality and performance",
|
||||||
|
2),
|
||||||
|
)
|
||||||
|
|
||||||
enum_direct_light_sampling_type = (
|
enum_direct_light_sampling_type = (
|
||||||
('MULTIPLE_IMPORTANCE_SAMPLING',
|
('MULTIPLE_IMPORTANCE_SAMPLING',
|
||||||
"Multiple Importance Sampling",
|
"Multiple Importance Sampling",
|
||||||
|
@ -352,6 +363,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||||
items=enum_denoising_prefilter,
|
items=enum_denoising_prefilter,
|
||||||
default='ACCURATE',
|
default='ACCURATE',
|
||||||
)
|
)
|
||||||
|
denoising_quality: EnumProperty(
|
||||||
|
name="Denoising Quality",
|
||||||
|
description="Select between quality and performance tradeoffs when using OpenImageDenoise",
|
||||||
|
items=enum_denoising_quality,
|
||||||
|
default='HIGH',
|
||||||
|
)
|
||||||
denoising_input_passes: EnumProperty(
|
denoising_input_passes: EnumProperty(
|
||||||
name="Denoising Input Passes",
|
name="Denoising Input Passes",
|
||||||
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
|
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
|
||||||
|
@ -376,6 +393,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||||
items=enum_denoising_prefilter,
|
items=enum_denoising_prefilter,
|
||||||
default='FAST',
|
default='FAST',
|
||||||
)
|
)
|
||||||
|
preview_denoising_quality: EnumProperty(
|
||||||
|
name="Viewport Denoising Quality",
|
||||||
|
description="Select between quality and performance tradeoffs when using OpenImageDenoise",
|
||||||
|
items=enum_denoising_quality,
|
||||||
|
default='BALANCED',
|
||||||
|
)
|
||||||
preview_denoising_input_passes: EnumProperty(
|
preview_denoising_input_passes: EnumProperty(
|
||||||
name="Viewport Denoising Input Passes",
|
name="Viewport Denoising Input Passes",
|
||||||
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
|
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
|
||||||
|
|
|
@ -229,6 +229,7 @@ class CYCLES_RENDER_PT_sampling_viewport_denoise(CyclesButtonsPanel, Panel):
|
||||||
effective_preview_denoiser = get_effective_preview_denoiser(context)
|
effective_preview_denoiser = get_effective_preview_denoiser(context)
|
||||||
if effective_preview_denoiser == 'OPENIMAGEDENOISE':
|
if effective_preview_denoiser == 'OPENIMAGEDENOISE':
|
||||||
col.prop(cscene, "preview_denoising_prefilter", text="Prefilter")
|
col.prop(cscene, "preview_denoising_prefilter", text="Prefilter")
|
||||||
|
col.prop(cscene, "preview_denoising_quality", text="Quality")
|
||||||
|
|
||||||
col.prop(cscene, "preview_denoising_start_sample", text="Start Sample")
|
col.prop(cscene, "preview_denoising_start_sample", text="Start Sample")
|
||||||
|
|
||||||
|
@ -290,6 +291,7 @@ class CYCLES_RENDER_PT_sampling_render_denoise(CyclesButtonsPanel, Panel):
|
||||||
col.prop(cscene, "denoising_input_passes", text="Passes")
|
col.prop(cscene, "denoising_input_passes", text="Passes")
|
||||||
if cscene.denoiser == 'OPENIMAGEDENOISE':
|
if cscene.denoiser == 'OPENIMAGEDENOISE':
|
||||||
col.prop(cscene, "denoising_prefilter", text="Prefilter")
|
col.prop(cscene, "denoising_prefilter", text="Prefilter")
|
||||||
|
col.prop(cscene, "denoising_quality", text="Quality")
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_RENDER_PT_sampling_path_guiding(CyclesButtonsPanel, Panel):
|
class CYCLES_RENDER_PT_sampling_path_guiding(CyclesButtonsPanel, Panel):
|
||||||
|
|
|
@ -476,6 +476,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||||
integrator->set_use_denoise_pass_albedo(denoise_params.use_pass_albedo);
|
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_pass_normal(denoise_params.use_pass_normal);
|
||||||
integrator->set_denoiser_prefilter(denoise_params.prefilter);
|
integrator->set_denoiser_prefilter(denoise_params.prefilter);
|
||||||
|
integrator->set_denoiser_quality(denoise_params.quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* UPDATE_NONE as we don't want to tag the integrator as modified (this was done by the
|
/* UPDATE_NONE as we don't want to tag the integrator as modified (this was done by the
|
||||||
|
@ -970,6 +971,8 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
|
||||||
denoising.type = (DenoiserType)get_enum(cscene, "denoiser", DENOISER_NUM, DENOISER_NONE);
|
denoising.type = (DenoiserType)get_enum(cscene, "denoiser", DENOISER_NUM, DENOISER_NONE);
|
||||||
denoising.prefilter = (DenoiserPrefilter)get_enum(
|
denoising.prefilter = (DenoiserPrefilter)get_enum(
|
||||||
cscene, "denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_NONE);
|
cscene, "denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_NONE);
|
||||||
|
denoising.quality = (DenoiserQuality)get_enum(
|
||||||
|
cscene, "denoising_quality", DENOISER_QUALITY_NUM, DENOISER_QUALITY_HIGH);
|
||||||
|
|
||||||
input_passes = (DenoiserInput)get_enum(
|
input_passes = (DenoiserInput)get_enum(
|
||||||
cscene, "denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO_NORMAL);
|
cscene, "denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO_NORMAL);
|
||||||
|
@ -988,6 +991,9 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
|
||||||
cscene, "preview_denoiser", DENOISER_NUM, DENOISER_NONE);
|
cscene, "preview_denoiser", DENOISER_NUM, DENOISER_NONE);
|
||||||
denoising.prefilter = (DenoiserPrefilter)get_enum(
|
denoising.prefilter = (DenoiserPrefilter)get_enum(
|
||||||
cscene, "preview_denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_FAST);
|
cscene, "preview_denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_FAST);
|
||||||
|
denoising.quality = (DenoiserQuality)get_enum(
|
||||||
|
cscene, "preview_denoising_quality", DENOISER_QUALITY_NUM, DENOISER_QUALITY_BALANCED);
|
||||||
|
|
||||||
denoising.start_sample = get_int(cscene, "preview_denoising_start_sample");
|
denoising.start_sample = get_int(cscene, "preview_denoising_start_sample");
|
||||||
|
|
||||||
input_passes = (DenoiserInput)get_enum(
|
input_passes = (DenoiserInput)get_enum(
|
||||||
|
|
|
@ -48,12 +48,25 @@ const NodeEnum *DenoiseParams::get_prefilter_enum()
|
||||||
return &prefilter_enum;
|
return &prefilter_enum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const NodeEnum *DenoiseParams::get_quality_enum()
|
||||||
|
{
|
||||||
|
static NodeEnum quality_enum;
|
||||||
|
|
||||||
|
if (quality_enum.empty()) {
|
||||||
|
quality_enum.insert("high", DENOISER_QUALITY_HIGH);
|
||||||
|
quality_enum.insert("balanced", DENOISER_QUALITY_BALANCED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &quality_enum;
|
||||||
|
}
|
||||||
|
|
||||||
NODE_DEFINE(DenoiseParams)
|
NODE_DEFINE(DenoiseParams)
|
||||||
{
|
{
|
||||||
NodeType *type = NodeType::add("denoise_params", create);
|
NodeType *type = NodeType::add("denoise_params", create);
|
||||||
|
|
||||||
const NodeEnum *type_enum = get_type_enum();
|
const NodeEnum *type_enum = get_type_enum();
|
||||||
const NodeEnum *prefilter_enum = get_prefilter_enum();
|
const NodeEnum *prefilter_enum = get_prefilter_enum();
|
||||||
|
const NodeEnum *quality_enum = get_quality_enum();
|
||||||
|
|
||||||
SOCKET_BOOLEAN(use, "Use", false);
|
SOCKET_BOOLEAN(use, "Use", false);
|
||||||
|
|
||||||
|
@ -67,6 +80,7 @@ NODE_DEFINE(DenoiseParams)
|
||||||
SOCKET_BOOLEAN(temporally_stable, "Temporally Stable", false);
|
SOCKET_BOOLEAN(temporally_stable, "Temporally Stable", false);
|
||||||
|
|
||||||
SOCKET_ENUM(prefilter, "Prefilter", *prefilter_enum, DENOISER_PREFILTER_FAST);
|
SOCKET_ENUM(prefilter, "Prefilter", *prefilter_enum, DENOISER_PREFILTER_FAST);
|
||||||
|
SOCKET_ENUM(quality, "Quality", *quality_enum, DENOISER_QUALITY_HIGH);
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,12 @@ enum DenoiserPrefilter {
|
||||||
DENOISER_PREFILTER_NUM,
|
DENOISER_PREFILTER_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DenoiserQuality {
|
||||||
|
DENOISER_QUALITY_HIGH = 1,
|
||||||
|
DENOISER_QUALITY_BALANCED = 2,
|
||||||
|
DENOISER_QUALITY_NUM,
|
||||||
|
};
|
||||||
|
|
||||||
/* NOTE: Is not a real scene node. Using Node API for ease of (de)serialization.
|
/* NOTE: Is not a real scene node. Using Node API for ease of (de)serialization.
|
||||||
* The default values here do not really matter as they are always initialized from the
|
* The default values here do not really matter as they are always initialized from the
|
||||||
* Integrator node. */
|
* Integrator node. */
|
||||||
|
@ -64,19 +70,13 @@ class DenoiseParams : public Node {
|
||||||
bool temporally_stable = false;
|
bool temporally_stable = false;
|
||||||
|
|
||||||
DenoiserPrefilter prefilter = DENOISER_PREFILTER_FAST;
|
DenoiserPrefilter prefilter = DENOISER_PREFILTER_FAST;
|
||||||
|
DenoiserQuality quality = DENOISER_QUALITY_HIGH;
|
||||||
|
|
||||||
static const NodeEnum *get_type_enum();
|
static const NodeEnum *get_type_enum();
|
||||||
static const NodeEnum *get_prefilter_enum();
|
static const NodeEnum *get_prefilter_enum();
|
||||||
|
static const NodeEnum *get_quality_enum();
|
||||||
|
|
||||||
DenoiseParams();
|
DenoiseParams();
|
||||||
|
|
||||||
bool modified(const DenoiseParams &other) const
|
|
||||||
{
|
|
||||||
return !(use == other.use && type == other.type && start_sample == other.start_sample &&
|
|
||||||
use_pass_albedo == other.use_pass_albedo &&
|
|
||||||
use_pass_normal == other.use_pass_normal &&
|
|
||||||
temporally_stable == other.temporally_stable && prefilter == other.prefilter);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
|
|
@ -164,6 +164,18 @@ class OIDNDenoiseContext {
|
||||||
oidn_filter.setProgressMonitorFunction(oidn_progress_monitor_function, denoiser_);
|
oidn_filter.setProgressMonitorFunction(oidn_progress_monitor_function, denoiser_);
|
||||||
oidn_filter.set("hdr", true);
|
oidn_filter.set("hdr", true);
|
||||||
oidn_filter.set("srgb", false);
|
oidn_filter.set("srgb", false);
|
||||||
|
|
||||||
|
# if OIDN_VERSION_MAJOR >= 2
|
||||||
|
switch (denoise_params_.quality) {
|
||||||
|
case DENOISER_QUALITY_BALANCED:
|
||||||
|
oidn_filter.set("quality", OIDN_QUALITY_BALANCED);
|
||||||
|
break;
|
||||||
|
case DENOISER_QUALITY_HIGH:
|
||||||
|
default:
|
||||||
|
oidn_filter.set("quality", OIDN_QUALITY_HIGH);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
if (denoise_params_.prefilter == DENOISER_PREFILTER_NONE ||
|
if (denoise_params_.prefilter == DENOISER_PREFILTER_NONE ||
|
||||||
denoise_params_.prefilter == DENOISER_PREFILTER_ACCURATE)
|
denoise_params_.prefilter == DENOISER_PREFILTER_ACCURATE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -108,7 +108,8 @@ bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
|
||||||
{
|
{
|
||||||
const bool recreate_denoiser = (oidn_device_ == nullptr) || (oidn_filter_ == nullptr) ||
|
const bool recreate_denoiser = (oidn_device_ == nullptr) || (oidn_filter_ == nullptr) ||
|
||||||
(use_pass_albedo_ != context.use_pass_albedo) ||
|
(use_pass_albedo_ != context.use_pass_albedo) ||
|
||||||
(use_pass_normal_ != context.use_pass_normal);
|
(use_pass_normal_ != context.use_pass_normal) ||
|
||||||
|
(quality_ != params_.quality);
|
||||||
if (!recreate_denoiser) {
|
if (!recreate_denoiser) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -153,6 +154,18 @@ bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
|
||||||
oidnSetFilterInt(oidn_filter_, "cleanAux", true);
|
oidnSetFilterInt(oidn_filter_, "cleanAux", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if OIDN_VERSION_MAJOR >= 2
|
||||||
|
switch (params_.quality) {
|
||||||
|
case DENOISER_QUALITY_BALANCED:
|
||||||
|
oidnSetFilterInt(oidn_filter_, "quality", OIDN_QUALITY_BALANCED);
|
||||||
|
break;
|
||||||
|
case DENOISER_QUALITY_HIGH:
|
||||||
|
default:
|
||||||
|
oidnSetFilterInt(oidn_filter_, "quality", OIDN_QUALITY_HIGH);
|
||||||
|
}
|
||||||
|
quality_ = params_.quality;
|
||||||
|
# endif
|
||||||
|
|
||||||
if (context.use_pass_albedo) {
|
if (context.use_pass_albedo) {
|
||||||
albedo_filter_ = create_filter();
|
albedo_filter_ = create_filter();
|
||||||
if (albedo_filter_ == nullptr) {
|
if (albedo_filter_ == nullptr) {
|
||||||
|
|
|
@ -66,6 +66,7 @@ class OIDNDenoiserGPU : public DenoiserGPU {
|
||||||
|
|
||||||
bool use_pass_albedo_ = false;
|
bool use_pass_albedo_ = false;
|
||||||
bool use_pass_normal_ = false;
|
bool use_pass_normal_ = false;
|
||||||
|
DenoiserQuality quality_ = DENOISER_QUALITY_HIGH;
|
||||||
|
|
||||||
int max_mem_ = 3000;
|
int max_mem_ = 3000;
|
||||||
};
|
};
|
||||||
|
|
|
@ -136,6 +136,10 @@ NODE_DEFINE(Integrator)
|
||||||
denoiser_prefilter_enum.insert("fast", DENOISER_PREFILTER_FAST);
|
denoiser_prefilter_enum.insert("fast", DENOISER_PREFILTER_FAST);
|
||||||
denoiser_prefilter_enum.insert("accurate", DENOISER_PREFILTER_ACCURATE);
|
denoiser_prefilter_enum.insert("accurate", DENOISER_PREFILTER_ACCURATE);
|
||||||
|
|
||||||
|
static NodeEnum denoiser_quality_enum;
|
||||||
|
denoiser_quality_enum.insert("high", DENOISER_QUALITY_HIGH);
|
||||||
|
denoiser_quality_enum.insert("balanced", DENOISER_QUALITY_BALANCED);
|
||||||
|
|
||||||
/* Default to accurate denoising with OpenImageDenoise. For interactive viewport
|
/* Default to accurate denoising with OpenImageDenoise. For interactive viewport
|
||||||
* it's best use OptiX and disable the normal pass since it does not always have
|
* it's best use OptiX and disable the normal pass since it does not always have
|
||||||
* the desired effect for that denoiser. */
|
* the desired effect for that denoiser. */
|
||||||
|
@ -148,6 +152,7 @@ NODE_DEFINE(Integrator)
|
||||||
"Denoiser Prefilter",
|
"Denoiser Prefilter",
|
||||||
denoiser_prefilter_enum,
|
denoiser_prefilter_enum,
|
||||||
DENOISER_PREFILTER_ACCURATE);
|
DENOISER_PREFILTER_ACCURATE);
|
||||||
|
SOCKET_ENUM(denoiser_quality, "Denoiser Quality", denoiser_quality_enum, DENOISER_QUALITY_HIGH);
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -399,6 +404,7 @@ DenoiseParams Integrator::get_denoise_params() const
|
||||||
denoise_params.use_pass_normal = use_denoise_pass_normal;
|
denoise_params.use_pass_normal = use_denoise_pass_normal;
|
||||||
|
|
||||||
denoise_params.prefilter = denoiser_prefilter;
|
denoise_params.prefilter = denoiser_prefilter;
|
||||||
|
denoise_params.quality = denoiser_quality;
|
||||||
|
|
||||||
return denoise_params;
|
return denoise_params;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ class Integrator : public Node {
|
||||||
NODE_SOCKET_API(bool, use_denoise_pass_albedo);
|
NODE_SOCKET_API(bool, use_denoise_pass_albedo);
|
||||||
NODE_SOCKET_API(bool, use_denoise_pass_normal);
|
NODE_SOCKET_API(bool, use_denoise_pass_normal);
|
||||||
NODE_SOCKET_API(DenoiserPrefilter, denoiser_prefilter);
|
NODE_SOCKET_API(DenoiserPrefilter, denoiser_prefilter);
|
||||||
|
NODE_SOCKET_API(DenoiserQuality, denoiser_quality);
|
||||||
|
|
||||||
enum : uint32_t {
|
enum : uint32_t {
|
||||||
AO_PASS_MODIFIED = (1 << 0),
|
AO_PASS_MODIFIED = (1 << 0),
|
||||||
|
|
Loading…
Reference in New Issue