Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2020-06-01 00:49:10 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-06-24 16:17:36 +0300
commit0a3bde63006c66b8b8531ed5eccca9bdf5e5dc20 (patch)
treecf4a577e1fb0cfdaf0c47d56879ae49a21b68c1d /intern/cycles/blender
parent88157b9efb2027380c4083d06e4ed61d8d109cef (diff)
Cycles: add denoising settings to the render properties
Enabling render and viewport denoising is now both done from the render properties. View layers still can individually be enabled/disabled for denoising and have their own denoising parameters. Note that the denoising engine also affects how denoising data passes are output even if no denoising happens on the render itself, to make the passes compatible with the engine. This includes internal refactoring for how denoising parameters are passed along, trying to avoid code duplication and unclear naming. Ref T76259
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r--intern/cycles/blender/addon/properties.py58
-rw-r--r--intern/cycles/blender/addon/ui.py68
-rw-r--r--intern/cycles/blender/blender_camera.cpp6
-rw-r--r--intern/cycles/blender/blender_device.cpp50
-rw-r--r--intern/cycles/blender/blender_session.cpp118
-rw-r--r--intern/cycles/blender/blender_sync.cpp116
-rw-r--r--intern/cycles/blender/blender_sync.h20
-rw-r--r--intern/cycles/blender/blender_viewport.cpp16
-rw-r--r--intern/cycles/blender/blender_viewport.h4
9 files changed, 260 insertions, 196 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index b7e9b1511ec..061e3784b0d 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -182,10 +182,20 @@ enum_aov_types = (
('COLOR', "Color", "Write a Color pass", 1),
)
-enum_viewport_denoising = (
- ('NONE', "None", "Disable viewport denoising", 0),
- ('OPTIX', "OptiX AI-Accelerated", "Use the OptiX denoiser running on the GPU (requires at least one compatible OptiX device)", 1),
-)
+def enum_optix_denoiser(self, context):
+ if not context or bool(context.preferences.addons[__package__].preferences.get_devices_for_type('OPTIX')):
+ return [('OPTIX', "OptiX", "Use the OptiX AI denoiser with GPU acceleration, only available on NVIDIA GPUs", 2)]
+ return []
+
+def enum_preview_denoiser(self, context):
+ items = [('AUTO', "Auto", "Use the fastest available denoiser for viewport rendering", 0)]
+ items += enum_optix_denoiser(self, context)
+ return items
+
+def enum_denoiser(self, context):
+ items = [('NLM', "NLM", "Cycles native non-local means denoiser, running on any compute device", 1)]
+ items += enum_optix_denoiser(self, context)
+ return items
enum_denoising_optix_input_passes = (
('RGB', "Color", "Use only color as input", 1),
@@ -224,11 +234,29 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Pause all viewport preview renders",
default=False,
)
- preview_denoising: EnumProperty(
- name="Viewport Denoising",
- description="Denoise the image after each preview update with the selected denoiser engine",
- items=enum_viewport_denoising,
- default='NONE',
+
+ use_denoising: BoolProperty(
+ name="Use Denoising",
+ description="Denoise the rendered image",
+ default=False,
+ )
+ use_preview_denoising: BoolProperty(
+ name="Use Viewport Denoising",
+ description="Denoise the image in the 3D viewport",
+ default=False,
+ )
+
+ denoiser: EnumProperty(
+ name="Denoiser",
+ description="Denoise the image with the selected denoiser",
+ items=enum_denoiser,
+ default=1,
+ )
+ preview_denoiser: EnumProperty(
+ name="Viewport Denoiser",
+ description="Denoise the image after each preview update with the selected denoiser",
+ items=enum_preview_denoiser,
+ default=0,
)
use_square_samples: BoolProperty(
@@ -244,7 +272,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default=128,
)
preview_samples: IntProperty(
- name="Preview Samples",
+ name="Viewport Samples",
description="Number of samples to render in the viewport, unlimited if 0",
min=0, max=(1 << 24),
default=32,
@@ -464,7 +492,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
subtype='PIXEL'
)
preview_dicing_rate: FloatProperty(
- name="Preview Dicing Rate",
+ name="Viewport Dicing Rate",
description="Size of a micropolygon in pixels during preview render",
min=0.1, max=1000.0, soft_min=0.5,
default=8.0,
@@ -1330,7 +1358,7 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
use_denoising: BoolProperty(
name="Use Denoising",
description="Denoise the rendered image",
- default=False,
+ default=True,
update=update_render_passes,
)
denoising_diffuse_direct: BoolProperty(
@@ -1400,12 +1428,6 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
default=0,
)
- use_optix_denoising: BoolProperty(
- name="OptiX AI-Accelerated",
- description="Use the OptiX denoiser to denoise the rendered image",
- default=False,
- update=update_render_passes,
- )
denoising_optix_input_passes: EnumProperty(
name="Input Passes",
description="Passes handed over to the OptiX denoiser (this can have different effects on the denoised image)",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 85da1a17c2b..e689ec90983 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -112,10 +112,6 @@ def show_device_active(context):
return True
return context.preferences.addons[__package__].preferences.has_active_device()
-def show_optix_denoising(context):
- # OptiX AI denoiser can be used when at least one device supports OptiX
- return bool(context.preferences.addons[__package__].preferences.get_devices_for_type('OPTIX'))
-
def draw_samples_info(layout, context):
cscene = context.scene.cycles
@@ -190,11 +186,6 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
col.prop(cscene, "aa_samples", text="Render")
col.prop(cscene, "preview_aa_samples", text="Viewport")
- # Viewport denoising is currently only supported with OptiX
- if show_optix_denoising(context):
- col = layout.column()
- col.prop(cscene, "preview_denoising")
-
if not use_branched_path(context):
draw_samples_info(layout, context)
@@ -256,6 +247,39 @@ class CYCLES_RENDER_PT_sampling_adaptive(CyclesButtonsPanel, Panel):
col.prop(cscene, "adaptive_threshold", text="Noise Threshold")
col.prop(cscene, "adaptive_min_samples", text="Min Samples")
+
+class CYCLES_RENDER_PT_sampling_denoising(CyclesButtonsPanel, Panel):
+ bl_label = "Denoising"
+ bl_parent_id = "CYCLES_RENDER_PT_sampling"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ cscene = scene.cycles
+
+ heading = layout.column(align=True, heading="Render")
+ row = heading.row(align=True)
+ row.prop(cscene, "use_denoising", text="")
+ sub = row.row()
+ sub.active = cscene.use_denoising
+ sub.prop(cscene, "denoiser", text="")
+
+ heading = layout.column(align=True, heading="Viewport")
+ row = heading.row(align=True)
+ row.prop(cscene, "use_preview_denoising", text="")
+ sub = row.row()
+ sub.active = cscene.use_preview_denoising
+ sub.prop(cscene, "preview_denoiser", text="")
+
+ sub = heading.row(align=True)
+ sub.active = cscene.use_preview_denoising
+ sub.prop(cscene, "preview_denoising_start_sample", text="Start Sample")
+
+
class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
bl_label = "Advanced"
bl_parent_id = "CYCLES_RENDER_PT_sampling"
@@ -730,11 +754,6 @@ class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel):
col.prop(rd, "preview_pixel_size", text="Pixel Size")
col.prop(cscene, "preview_start_resolution", text="Start Pixels")
- if show_optix_denoising(context):
- sub = col.row(align=True)
- sub.active = cscene.preview_denoising != 'NONE'
- sub.prop(cscene, "preview_denoising_start_sample", text="Denoising Start Sample")
-
class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
bl_label = "Filter"
@@ -957,12 +976,17 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
bl_context = "view_layer"
bl_options = {'DEFAULT_CLOSED'}
+ @classmethod
+ def poll(cls, context):
+ cscene = context.scene.cycles
+ return CyclesButtonsPanel.poll(context) and cscene.use_denoising
+
def draw_header(self, context):
scene = context.scene
view_layer = context.view_layer
cycles_view_layer = view_layer.cycles
- layout = self.layout
+ layout = self.layout
layout.prop(cycles_view_layer, "use_denoising", text="")
def draw(self, context):
@@ -973,18 +997,15 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
scene = context.scene
view_layer = context.view_layer
cycles_view_layer = view_layer.cycles
+ denoiser = scene.cycles.denoiser
- layout.active = cycles_view_layer.use_denoising
+ layout.active = denoiser != 'NONE' and cycles_view_layer.use_denoising
col = layout.column()
- if show_optix_denoising(context):
- col.prop(cycles_view_layer, "use_optix_denoising")
- col.separator(factor=2.0)
-
- if cycles_view_layer.use_optix_denoising:
- col.prop(cycles_view_layer, "denoising_optix_input_passes")
- return
+ if denoiser == 'OPTIX':
+ col.prop(cycles_view_layer, "denoising_optix_input_passes")
+ return
col.prop(cycles_view_layer, "denoising_radius", text="Radius")
@@ -2237,6 +2258,7 @@ classes = (
CYCLES_RENDER_PT_sampling,
CYCLES_RENDER_PT_sampling_sub_samples,
CYCLES_RENDER_PT_sampling_adaptive,
+ CYCLES_RENDER_PT_sampling_denoising,
CYCLES_RENDER_PT_sampling_advanced,
CYCLES_RENDER_PT_light_paths,
CYCLES_RENDER_PT_light_paths_max_bounces,
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 40a1a2c2edc..d9c63bec737 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -873,7 +873,8 @@ BufferParams BlenderSync::get_buffer_params(BL::Scene &b_scene,
BL::RegionView3D &b_rv3d,
Camera *cam,
int width,
- int height)
+ int height,
+ const bool use_denoiser)
{
BufferParams params;
bool use_border = false;
@@ -907,8 +908,7 @@ BufferParams BlenderSync::get_buffer_params(BL::Scene &b_scene,
PassType display_pass = update_viewport_display_passes(b_v3d, params.passes);
/* Can only denoise the combined image pass */
- params.denoising_data_pass = display_pass == PASS_COMBINED &&
- update_viewport_display_denoising(b_v3d, b_scene);
+ params.denoising_data_pass = display_pass == PASS_COMBINED && use_denoiser;
return params;
}
diff --git a/intern/cycles/blender/blender_device.cpp b/intern/cycles/blender/blender_device.cpp
index ac52948806c..fb9ab9e8c97 100644
--- a/intern/cycles/blender/blender_device.cpp
+++ b/intern/cycles/blender/blender_device.cpp
@@ -21,13 +21,6 @@
CCL_NAMESPACE_BEGIN
-enum DenoiserType {
- DENOISER_NONE = 0,
- DENOISER_OPTIX = 1,
-
- DENOISER_NUM
-};
-
enum ComputeDevice {
COMPUTE_DEVICE_CPU = 0,
COMPUTE_DEVICE_CUDA = 1,
@@ -120,49 +113,6 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
}
}
- /* Ensure there is an OptiX device when using the OptiX denoiser. */
- bool use_optix_denoising = get_enum(cscene, "preview_denoising", DENOISER_NUM, DENOISER_NONE) ==
- DENOISER_OPTIX &&
- !background;
- BL::Scene::view_layers_iterator b_view_layer;
- for (b_scene.view_layers.begin(b_view_layer); b_view_layer != b_scene.view_layers.end();
- ++b_view_layer) {
- PointerRNA crl = RNA_pointer_get(&b_view_layer->ptr, "cycles");
- if (get_boolean(crl, "use_optix_denoising")) {
- use_optix_denoising = true;
- }
- }
-
- if (use_optix_denoising && device.type != DEVICE_OPTIX) {
- vector<DeviceInfo> optix_devices = Device::available_devices(DEVICE_MASK_OPTIX);
- if (!optix_devices.empty()) {
- /* Convert to a special multi device with separate denoising devices. */
- if (device.multi_devices.empty()) {
- device.multi_devices.push_back(device);
- }
-
- /* Try to use the same physical devices for denoising. */
- for (const DeviceInfo &cuda_device : device.multi_devices) {
- if (cuda_device.type == DEVICE_CUDA) {
- for (const DeviceInfo &optix_device : optix_devices) {
- if (cuda_device.num == optix_device.num) {
- device.id += optix_device.id;
- device.denoising_devices.push_back(optix_device);
- break;
- }
- }
- }
- }
-
- if (device.denoising_devices.empty()) {
- /* Simply use the first available OptiX device. */
- const DeviceInfo optix_device = optix_devices.front();
- device.id += optix_device.id; /* Uniquely identify this special multi device. */
- device.denoising_devices.push_back(optix_device);
- }
- }
- }
-
return device;
}
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index dbe87ce2b13..2874ccb6470 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -157,8 +157,14 @@ void BlenderSession::create_session()
}
/* set buffer parameters */
- BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene,
+ b_render,
+ b_v3d,
+ b_rv3d,
+ scene->camera,
+ width,
+ height,
+ session_params.denoising.use);
session->reset(buffer_params, session_params.samples);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
@@ -239,8 +245,14 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
- BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_scene, b_render, b_null_space_view3d, b_null_region_view3d, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene,
+ b_render,
+ b_null_space_view3d,
+ b_null_region_view3d,
+ scene->camera,
+ width,
+ height,
+ session_params.denoising.use);
session->reset(buffer_params, session_params.samples);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
@@ -468,14 +480,19 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
session->update_render_tile_cb = function_bind(
&BlenderSession::update_render_tile, this, _1, _2);
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+
/* get buffer parameters */
SessionParams session_params = BlenderSync::get_session_params(
- b_engine, b_userpref, b_scene, background);
- BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
-
- /* render each layer */
- BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+ b_engine, b_userpref, b_scene, background, b_view_layer);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene,
+ b_render,
+ b_v3d,
+ b_rv3d,
+ scene->camera,
+ width,
+ height,
+ session_params.denoising.use);
/* temporary render result to find needed passes and views */
BL::RenderResult b_rr = begin_render_result(
@@ -485,35 +502,26 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
BL::RenderLayer b_rlay = *b_single_rlay;
b_rlay_name = b_view_layer.name();
- /* add passes */
- vector<Pass> passes = sync->sync_render_passes(
- b_rlay, b_view_layer, session_params.adaptive_sampling);
- buffer_params.passes = passes;
+ /* Update denoising parameters. */
+ session->set_denoising(session_params.denoising);
- PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
- bool use_denoising = get_boolean(crl, "use_denoising");
- bool use_optix_denoising = get_boolean(crl, "use_optix_denoising");
- bool write_denoising_passes = get_boolean(crl, "denoising_store_passes");
+ bool use_denoising = session_params.denoising.use;
+ bool store_denoising_passes = session_params.denoising.store_passes;
- buffer_params.denoising_data_pass = use_denoising || write_denoising_passes;
+ buffer_params.denoising_data_pass = use_denoising || store_denoising_passes;
buffer_params.denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
- buffer_params.denoising_prefiltered_pass = write_denoising_passes && !use_optix_denoising;
-
- session->params.run_denoising = use_denoising || write_denoising_passes;
- session->params.full_denoising = use_denoising && !use_optix_denoising;
- session->params.optix_denoising = use_denoising && use_optix_denoising;
- session->params.write_denoising_passes = write_denoising_passes && !use_optix_denoising;
- session->params.denoising.radius = get_int(crl, "denoising_radius");
- session->params.denoising.strength = get_float(crl, "denoising_strength");
- session->params.denoising.feature_strength = get_float(crl, "denoising_feature_strength");
- session->params.denoising.relative_pca = get_boolean(crl, "denoising_relative_pca");
- session->params.denoising.optix_input_passes = get_enum(crl, "denoising_optix_input_passes");
- session->tile_manager.schedule_denoising = session->params.run_denoising;
+ buffer_params.denoising_prefiltered_pass = store_denoising_passes &&
+ session_params.denoising.type == DENOISER_NLM;
scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
scene->film->denoising_clean_pass = buffer_params.denoising_clean_pass;
scene->film->denoising_prefiltered_pass = buffer_params.denoising_prefiltered_pass;
+ /* Add passes */
+ vector<Pass> passes = sync->sync_render_passes(
+ b_rlay, b_view_layer, session_params.adaptive_sampling, session_params.denoising);
+ buffer_params.passes = passes;
+
scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
scene->film->tag_passes_update(scene, passes);
scene->film->tag_update(scene);
@@ -798,7 +806,7 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
/* increase samples, but never decrease */
session->set_samples(session_params.samples);
- session->set_denoising_start_sample(session_params.denoising_start_sample);
+ session->set_denoising_start_sample(session_params.denoising.start_sample);
session->set_pause(session_pause);
/* copy recalc flags, outside of mutex so we can decide to do the real
@@ -830,22 +838,24 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
sync->sync_camera(b_render, b_camera_override, width, height, "");
/* get buffer parameters */
- BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
-
- if (session_params.device.type != DEVICE_OPTIX &&
- session_params.device.denoising_devices.empty()) {
- /* cannot use OptiX denoising when it is not supported by the device. */
- buffer_params.denoising_data_pass = false;
- }
- else {
- session->set_denoising(buffer_params.denoising_data_pass, true);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene,
+ b_render,
+ b_v3d,
+ b_rv3d,
+ scene->camera,
+ width,
+ height,
+ session_params.denoising.use);
+
+ if (!buffer_params.denoising_data_pass) {
+ session_params.denoising.use = false;
}
+ session->set_denoising(session_params.denoising);
+
+ /* Update film if denoising data was enabled or disabled. */
if (scene->film->denoising_data_pass != buffer_params.denoising_data_pass) {
scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
-
- /* Force a scene and session reset below. */
scene->film->tag_update(scene);
}
@@ -916,8 +926,14 @@ bool BlenderSession::draw(int w, int h)
if (reset) {
SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
- BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene,
+ b_render,
+ b_v3d,
+ b_rv3d,
+ scene->camera,
+ width,
+ height,
+ session_params.denoising.use);
bool session_pause = BlenderSync::get_session_pause(b_scene, background);
if (session_pause == false) {
@@ -934,8 +950,14 @@ bool BlenderSession::draw(int w, int h)
update_status_progress();
/* draw */
- BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene,
+ b_render,
+ b_v3d,
+ b_rv3d,
+ scene->camera,
+ width,
+ height,
+ session->params.denoising.use);
DeviceDrawParams draw_params;
if (session->params.display_buffer_linear) {
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index b40c8434395..aed92cf1376 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -537,7 +537,8 @@ int BlenderSync::get_denoising_pass(BL::RenderPass &b_pass)
vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
BL::ViewLayer &b_view_layer,
- bool adaptive_sampling)
+ bool adaptive_sampling,
+ const DenoiseParams &denoising)
{
vector<Pass> passes;
@@ -554,16 +555,13 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
Pass::add(pass_type, passes, b_pass.name().c_str());
}
- PointerRNA crp = RNA_pointer_get(&b_view_layer.ptr, "cycles");
- bool use_denoising = get_boolean(crp, "use_denoising");
- bool use_optix_denoising = get_boolean(crp, "use_optix_denoising");
- bool write_denoising_passes = get_boolean(crp, "denoising_store_passes");
+ PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
scene->film->denoising_flags = 0;
- if (use_denoising || write_denoising_passes) {
- if (!use_optix_denoising) {
+ if (denoising.use || denoising.store_passes) {
+ if (denoising.type == DENOISER_NLM) {
#define MAP_OPTION(name, flag) \
- if (!get_boolean(crp, name)) \
+ if (!get_boolean(crl, name)) \
scene->film->denoising_flags |= flag;
MAP_OPTION("denoising_diffuse_direct", DENOISING_CLEAN_DIFFUSE_DIR);
MAP_OPTION("denoising_diffuse_indirect", DENOISING_CLEAN_DIFFUSE_IND);
@@ -576,11 +574,11 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
}
- if (write_denoising_passes) {
+ if (denoising.store_passes) {
b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str());
- if (!use_optix_denoising) {
+ if (denoising.type == DENOISER_NLM) {
b_engine.add_pass("Denoising Shadowing", 1, "X", b_view_layer.name().c_str());
b_engine.add_pass("Denoising Variance", 3, "RGB", b_view_layer.name().c_str());
b_engine.add_pass("Denoising Intensity", 1, "X", b_view_layer.name().c_str());
@@ -592,46 +590,46 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
}
#ifdef __KERNEL_DEBUG__
- if (get_boolean(crp, "pass_debug_bvh_traversed_nodes")) {
+ if (get_boolean(crl, "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, "Debug BVH Traversed Nodes");
}
- if (get_boolean(crp, "pass_debug_bvh_traversed_instances")) {
+ if (get_boolean(crl, "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, "Debug BVH Traversed Instances");
}
- if (get_boolean(crp, "pass_debug_bvh_intersections")) {
+ if (get_boolean(crl, "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, "Debug BVH Intersections");
}
- if (get_boolean(crp, "pass_debug_ray_bounces")) {
+ if (get_boolean(crl, "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, "Debug Ray Bounces");
}
#endif
- if (get_boolean(crp, "pass_debug_render_time")) {
+ if (get_boolean(crl, "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, "Debug Render Time");
}
- if (get_boolean(crp, "pass_debug_sample_count")) {
+ if (get_boolean(crl, "pass_debug_sample_count")) {
b_engine.add_pass("Debug Sample Count", 1, "X", b_view_layer.name().c_str());
Pass::add(PASS_SAMPLE_COUNT, passes, "Debug Sample Count");
}
- if (get_boolean(crp, "use_pass_volume_direct")) {
+ if (get_boolean(crl, "use_pass_volume_direct")) {
b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str());
Pass::add(PASS_VOLUME_DIRECT, passes, "VolumeDir");
}
- if (get_boolean(crp, "use_pass_volume_indirect")) {
+ if (get_boolean(crl, "use_pass_volume_indirect")) {
b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str());
Pass::add(PASS_VOLUME_INDIRECT, passes, "VolumeInd");
}
/* Cryptomatte stores two ID/weight pairs per RGBA layer.
* User facing parameter is the number of pairs. */
- int crypto_depth = divide_up(min(16, get_int(crp, "pass_crypto_depth")), 2);
+ int crypto_depth = divide_up(min(16, get_int(crl, "pass_crypto_depth")), 2);
scene->film->cryptomatte_depth = crypto_depth;
scene->film->cryptomatte_passes = CRYPT_NONE;
- if (get_boolean(crp, "use_pass_crypto_object")) {
+ if (get_boolean(crl, "use_pass_crypto_object")) {
for (int i = 0; i < crypto_depth; i++) {
string passname = cryptomatte_prefix + string_printf("Object%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
@@ -640,7 +638,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
CRYPT_OBJECT);
}
- if (get_boolean(crp, "use_pass_crypto_material")) {
+ if (get_boolean(crl, "use_pass_crypto_material")) {
for (int i = 0; i < crypto_depth; i++) {
string passname = cryptomatte_prefix + string_printf("Material%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
@@ -649,7 +647,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
CRYPT_MATERIAL);
}
- if (get_boolean(crp, "use_pass_crypto_asset")) {
+ if (get_boolean(crl, "use_pass_crypto_asset")) {
for (int i = 0; i < crypto_depth; i++) {
string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
@@ -658,19 +656,19 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
CRYPT_ASSET);
}
- if (get_boolean(crp, "pass_crypto_accurate") && scene->film->cryptomatte_passes != CRYPT_NONE) {
+ if (get_boolean(crl, "pass_crypto_accurate") && scene->film->cryptomatte_passes != CRYPT_NONE) {
scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes |
CRYPT_ACCURATE);
}
if (adaptive_sampling) {
Pass::add(PASS_ADAPTIVE_AUX_BUFFER, passes);
- if (!get_boolean(crp, "pass_debug_sample_count")) {
+ if (!get_boolean(crl, "pass_debug_sample_count")) {
Pass::add(PASS_SAMPLE_COUNT, passes);
}
}
- RNA_BEGIN (&crp, b_aov, "aovs") {
+ RNA_BEGIN (&crl, b_aov, "aovs") {
bool is_color = (get_enum(b_aov, "type") == 1);
string name = get_string(b_aov, "name");
@@ -773,7 +771,8 @@ bool BlenderSync::get_session_pause(BL::Scene &b_scene, bool background)
SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
BL::Preferences &b_preferences,
BL::Scene &b_scene,
- bool background)
+ bool background,
+ BL::ViewLayer b_view_layer)
{
SessionParams params;
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@@ -851,9 +850,22 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
params.tile_order = TILE_BOTTOM_TO_TOP;
}
- /* other parameters */
+ /* Denoising */
+ params.denoising = get_denoise_params(b_scene, b_view_layer, background);
+
+ if (params.denoising.use) {
+ /* Add additional denoising devices if we are rendering and denoising
+ * with different devices. */
+ params.device.add_denoising_devices(params.denoising.type);
+
+ /* Check if denoiser is supported by device. */
+ if (!(params.device.denoisers & params.denoising.type)) {
+ params.denoising.use = false;
+ }
+ }
+
+ /* Viewport Performance */
params.start_resolution = get_int(cscene, "preview_start_resolution");
- params.denoising_start_sample = get_int(cscene, "preview_denoising_start_sample");
params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
/* other parameters */
@@ -906,4 +918,52 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
return params;
}
+DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
+ BL::ViewLayer &b_view_layer,
+ bool background)
+{
+ DenoiseParams denoising;
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+ if (background) {
+ /* Final Render Denoising */
+ denoising.use = get_boolean(cscene, "use_denoising");
+ denoising.type = (DenoiserType)get_enum(cscene, "denoiser", DENOISER_NUM, DENOISER_NONE);
+
+ if (b_view_layer) {
+ PointerRNA clayer = RNA_pointer_get(&b_view_layer.ptr, "cycles");
+ if (!get_boolean(clayer, "use_denoising")) {
+ denoising.use = false;
+ }
+
+ denoising.radius = get_int(clayer, "denoising_radius");
+ denoising.strength = get_float(clayer, "denoising_strength");
+ denoising.feature_strength = get_float(clayer, "denoising_feature_strength");
+ denoising.relative_pca = get_boolean(clayer, "denoising_relative_pca");
+ denoising.optix_input_passes = get_enum(clayer, "denoising_optix_input_passes");
+
+ denoising.store_passes = get_boolean(clayer, "denoising_store_passes");
+ }
+ }
+ else {
+ /* Viewport Denoising */
+ denoising.use = get_boolean(cscene, "use_preview_denoising");
+ denoising.type = (DenoiserType)get_enum(
+ cscene, "preview_denoiser", DENOISER_NUM, DENOISER_NONE);
+ denoising.start_sample = get_int(cscene, "preview_denoising_start_sample");
+
+ /* Auto select fastest denoiser. */
+ if (denoising.type == DENOISER_NONE) {
+ if (!Device::available_devices(DEVICE_MASK_OPTIX).empty()) {
+ denoising.type = DENOISER_OPTIX;
+ }
+ else {
+ denoising.use = false;
+ }
+ }
+ }
+
+ return denoising;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 25032e8d0fa..85789cd00f6 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -75,7 +75,8 @@ class BlenderSync {
void sync_view_layer(BL::SpaceView3D &b_v3d, BL::ViewLayer &b_view_layer);
vector<Pass> sync_render_passes(BL::RenderLayer &b_render_layer,
BL::ViewLayer &b_view_layer,
- bool adaptive_sampling);
+ bool adaptive_sampling,
+ const DenoiseParams &denoising);
void sync_integrator();
void sync_camera(BL::RenderSettings &b_render,
BL::Object &b_override,
@@ -94,10 +95,12 @@ class BlenderSync {
/* get parameters */
static SceneParams get_scene_params(BL::Scene &b_scene, bool background);
- static SessionParams get_session_params(BL::RenderEngine &b_engine,
- BL::Preferences &b_userpref,
- BL::Scene &b_scene,
- bool background);
+ static SessionParams get_session_params(
+ BL::RenderEngine &b_engine,
+ BL::Preferences &b_userpref,
+ BL::Scene &b_scene,
+ bool background,
+ BL::ViewLayer b_view_layer = BL::ViewLayer(PointerRNA_NULL));
static bool get_session_pause(BL::Scene &b_scene, bool background);
static BufferParams get_buffer_params(BL::Scene &b_scene,
BL::RenderSettings &b_render,
@@ -105,12 +108,17 @@ class BlenderSync {
BL::RegionView3D &b_rv3d,
Camera *cam,
int width,
- int height);
+ int height,
+ const bool use_denoiser);
static PassType get_pass_type(BL::RenderPass &b_pass);
static int get_denoising_pass(BL::RenderPass &b_pass);
private:
+ static DenoiseParams get_denoise_params(BL::Scene &b_scene,
+ BL::ViewLayer &b_view_layer,
+ bool background);
+
/* sync */
void sync_lights(BL::Depsgraph &b_depsgraph, bool update_all);
void sync_materials(BL::Depsgraph &b_depsgraph, bool update_all);
diff --git a/intern/cycles/blender/blender_viewport.cpp b/intern/cycles/blender/blender_viewport.cpp
index 93e84e28032..73ef5f94720 100644
--- a/intern/cycles/blender/blender_viewport.cpp
+++ b/intern/cycles/blender/blender_viewport.cpp
@@ -61,17 +61,6 @@ const bool BlenderViewportParameters::custom_viewport_parameters() const
return !(use_scene_world && use_scene_lights);
}
-bool BlenderViewportParameters::get_viewport_display_denoising(BL::SpaceView3D &b_v3d,
- BL::Scene &b_scene)
-{
- bool use_denoising = false;
- if (b_v3d) {
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- use_denoising = get_enum(cscene, "preview_denoising") != 0;
- }
- return use_denoising;
-}
-
PassType BlenderViewportParameters::get_viewport_display_render_pass(BL::SpaceView3D &b_v3d)
{
PassType display_pass = PASS_NONE;
@@ -83,11 +72,6 @@ PassType BlenderViewportParameters::get_viewport_display_render_pass(BL::SpaceVi
return display_pass;
}
-bool update_viewport_display_denoising(BL::SpaceView3D &b_v3d, BL::Scene &b_scene)
-{
- return BlenderViewportParameters::get_viewport_display_denoising(b_v3d, b_scene);
-}
-
PassType update_viewport_display_passes(BL::SpaceView3D &b_v3d, vector<Pass> &passes)
{
if (b_v3d) {
diff --git a/intern/cycles/blender/blender_viewport.h b/intern/cycles/blender/blender_viewport.h
index 3e44e552f1d..7c6c9c4d274 100644
--- a/intern/cycles/blender/blender_viewport.h
+++ b/intern/cycles/blender/blender_viewport.h
@@ -44,15 +44,11 @@ class BlenderViewportParameters {
friend class BlenderSync;
public:
- /* Get whether to enable denoising data pass in viewport. */
- static bool get_viewport_display_denoising(BL::SpaceView3D &b_v3d, BL::Scene &b_scene);
/* Retrieve the render pass that needs to be displayed on the given `SpaceView3D`
* When the `b_v3d` parameter is not given `PASS_NONE` will be returned. */
static PassType get_viewport_display_render_pass(BL::SpaceView3D &b_v3d);
};
-bool update_viewport_display_denoising(BL::SpaceView3D &b_v3d, BL::Scene &b_scene);
-
PassType update_viewport_display_passes(BL::SpaceView3D &b_v3d, vector<Pass> &passes);
CCL_NAMESPACE_END