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:
authorPatrick Mours <pmours@nvidia.com>2020-02-11 18:30:01 +0300
committerPatrick Mours <pmours@nvidia.com>2020-02-11 20:03:43 +0300
commit38589de10c098cfe32ac7716f4d7844abf959753 (patch)
treed28b007bdc75e4eefd1d7ded5115655c50a72140 /intern/cycles/blender
parent35490c3ead03d472dbcba36c85d428e81b442520 (diff)
Cycles: Add support for denoising in the viewport
The OptiX denoiser can be a great help when rendering in the viewport, since it is really fast and needs few samples to produce convincing results. This patch therefore adds support for using any Cycles denoiser in the viewport also (but only the OptiX one is selectable because the NLM one is too slow to be usable currently). It also adds support for denoising on a different device than rendering (so one can e.g. render with the CPU but denoise with OptiX). Reviewed By: #cycles, brecht Differential Revision: https://developer.blender.org/D6554
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r--intern/cycles/blender/addon/properties.py44
-rw-r--r--intern/cycles/blender/addon/ui.py32
-rw-r--r--intern/cycles/blender/blender_camera.cpp9
-rw-r--r--intern/cycles/blender/blender_device.cpp53
-rw-r--r--intern/cycles/blender/blender_session.cpp35
-rw-r--r--intern/cycles/blender/blender_sync.cpp18
-rw-r--r--intern/cycles/blender/blender_sync.h3
-rw-r--r--intern/cycles/blender/blender_viewport.cpp16
-rw-r--r--intern/cycles/blender/blender_viewport.h4
9 files changed, 148 insertions, 66 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 5f163c2510b..eafe37618b3 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -197,7 +197,12 @@ enum_aov_types = (
('COLOR', "Color", "Write a Color pass", 1),
)
-enum_denoising_optix_input_passes= (
+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),
+)
+
+enum_denoising_optix_input_passes = (
('RGB', "Color", "Use only color as input", 1),
('RGB_ALBEDO', "Color + Albedo", "Use color and albedo data as input", 2),
('RGB_ALBEDO_NORMAL', "Color + Albedo + Normal", "Use color, albedo and normal data as input", 3),
@@ -229,6 +234,18 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default='PATH',
)
+ preview_pause: BoolProperty(
+ name="Pause Preview",
+ 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_square_samples: BoolProperty(
name="Square Samples",
description="Square sampling values for easier artist control",
@@ -247,11 +264,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
min=0, max=(1 << 24),
default=32,
)
- preview_pause: BoolProperty(
- name="Pause Preview",
- description="Pause all viewport preview renders",
- default=False,
- )
aa_samples: IntProperty(
name="AA Samples",
description="Number of antialiasing samples to render for each pixel",
@@ -264,6 +276,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
min=0, max=2097151,
default=32,
)
+
diffuse_samples: IntProperty(
name="Diffuse Samples",
description="Number of diffuse bounce samples to render for each AA sample",
@@ -294,14 +307,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
min=1, max=1024,
default=1,
)
-
subsurface_samples: IntProperty(
name="Subsurface Samples",
description="Number of subsurface scattering samples to render for each AA sample",
min=1, max=1024,
default=1,
)
-
volume_samples: IntProperty(
name="Volume Samples",
description="Number of volume scattering samples to render for each AA sample",
@@ -1305,12 +1316,6 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
default=False,
update=update_render_passes,
)
- use_optix_denoising: BoolProperty(
- name="Use OptiX AI Denoising",
- description="Denoise the rendered image with the OptiX AI denoiser",
- default=False,
- update=update_render_passes,
- )
denoising_diffuse_direct: BoolProperty(
name="Diffuse Direct",
description="Denoise the direct diffuse lighting",
@@ -1387,11 +1392,18 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
min=0, max=7,
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="Controls which passes the OptiX AI denoiser should use as input, which can have different effects on the denoised image",
+ description="Passes handed over to the OptiX denoiser (this can have different effects on the denoised image)",
items=enum_denoising_optix_input_passes,
- default='RGB',
+ default='RGB_ALBEDO',
)
use_pass_crypto_object: BoolProperty(
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 35d5d3801d2..f23d141e3da 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -112,6 +112,10 @@ 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
@@ -177,17 +181,23 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
if not use_optix(context):
layout.prop(cscene, "progressive")
- if cscene.progressive == 'PATH' or use_branched_path(context) is False:
+ if not use_branched_path(context):
col = layout.column(align=True)
col.prop(cscene, "samples", text="Render")
col.prop(cscene, "preview_samples", text="Viewport")
-
- draw_samples_info(layout, context)
else:
col = layout.column(align=True)
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)
+
class CYCLES_RENDER_PT_sampling_sub_samples(CyclesButtonsPanel, Panel):
bl_label = "Sub Samples"
@@ -195,9 +205,7 @@ class CYCLES_RENDER_PT_sampling_sub_samples(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
- scene = context.scene
- cscene = scene.cycles
- return cscene.progressive != 'PATH' and use_branched_path(context)
+ return use_branched_path(context)
def draw(self, context):
layout = self.layout
@@ -635,9 +643,6 @@ class CYCLES_RENDER_PT_performance_tiles(CyclesButtonsPanel, Panel):
sub = col.column()
sub.active = not rd.use_save_buffers
- for view_layer in scene.view_layers:
- if view_layer.cycles.use_denoising:
- sub.active = False
sub.prop(cscene, "use_progressive_refine")
@@ -981,15 +986,14 @@ class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
col = split.column(align=True)
- if use_optix(context):
- col.prop(cycles_view_layer, "use_optix_denoising", text="OptiX AI Denoising")
+ 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
- col.separator(factor=2.0)
-
col.prop(cycles_view_layer, "denoising_radius", text="Radius")
col.prop(cycles_view_layer, "denoising_strength", slider=True, text="Strength")
col.prop(cycles_view_layer, "denoising_feature_strength", slider=True, text="Feature Strength")
@@ -2192,8 +2196,6 @@ def draw_device(self, context):
col = layout.column()
col.prop(cscene, "feature_set")
- scene = context.scene
-
col = layout.column()
col.active = show_device_active(context)
col.prop(cscene, "device")
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index c84d6e1572b..990061dd9f1 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -863,7 +863,8 @@ void BlenderSync::sync_view(BL::SpaceView3D &b_v3d,
}
}
-BufferParams BlenderSync::get_buffer_params(BL::RenderSettings &b_render,
+BufferParams BlenderSync::get_buffer_params(BL::Scene &b_scene,
+ BL::RenderSettings &b_render,
BL::SpaceView3D &b_v3d,
BL::RegionView3D &b_rv3d,
Camera *cam,
@@ -899,7 +900,11 @@ BufferParams BlenderSync::get_buffer_params(BL::RenderSettings &b_render,
params.height = height;
}
- update_viewport_display_passes(b_v3d, params.passes);
+ 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);
return params;
}
diff --git a/intern/cycles/blender/blender_device.cpp b/intern/cycles/blender/blender_device.cpp
index 111fc8d5192..c3c307318a8 100644
--- a/intern/cycles/blender/blender_device.cpp
+++ b/intern/cycles/blender/blender_device.cpp
@@ -19,6 +19,22 @@
CCL_NAMESPACE_BEGIN
+enum DenoiserType {
+ DENOISER_NONE = 0,
+ DENOISER_OPTIX = 1,
+
+ DENOISER_NUM
+};
+
+enum ComputeDevice {
+ COMPUTE_DEVICE_CPU = 0,
+ COMPUTE_DEVICE_CUDA = 1,
+ COMPUTE_DEVICE_OPENCL = 2,
+ COMPUTE_DEVICE_OPTIX = 3,
+
+ COMPUTE_DEVICE_NUM
+};
+
int blender_device_threads(BL::Scene &b_scene)
{
BL::RenderSettings b_r = b_scene.render();
@@ -40,7 +56,7 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
/* Find network device. */
vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK_NETWORK);
if (!devices.empty()) {
- device = devices.front();
+ return devices.front();
}
}
else if (get_enum(cscene, "device") == 1) {
@@ -57,14 +73,6 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
}
/* Test if we are using GPU devices. */
- enum ComputeDevice {
- COMPUTE_DEVICE_CPU = 0,
- COMPUTE_DEVICE_CUDA = 1,
- COMPUTE_DEVICE_OPENCL = 2,
- COMPUTE_DEVICE_OPTIX = 3,
- COMPUTE_DEVICE_NUM = 4,
- };
-
ComputeDevice compute_device = (ComputeDevice)get_enum(
cpreferences, "compute_device_type", COMPUTE_DEVICE_NUM, COMPUTE_DEVICE_CPU);
@@ -106,6 +114,33 @@ 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 = DENOISER_OPTIX ==
+ get_enum(cscene, "preview_denoising", DENOISER_NUM, DENOISER_NONE);
+ 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);
+ }
+
+ /* 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 1490348743e..2e7a72d8072 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -166,7 +166,7 @@ void BlenderSession::create_session()
/* set buffer parameters */
BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
@@ -244,7 +244,7 @@ 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_render, b_null_space_view3d, b_null_region_view3d, scene->camera, width, height);
+ b_scene, b_render, b_null_space_view3d, b_null_region_view3d, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
@@ -460,7 +460,7 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ 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();
@@ -706,7 +706,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y());
@@ -851,7 +851,6 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
if (session->params.modified(session_params) || scene->params.modified(scene_params)) {
free_session();
create_session();
- return;
}
/* increase samples, but never decrease */
@@ -886,10 +885,28 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
else
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);
+ }
+
+ 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);
+ }
+
/* reset if needed */
if (scene->need_reset()) {
- BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_render, b_v3d, b_rv3d, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
/* After session reset, so device is not accessing image data anymore. */
@@ -956,7 +973,7 @@ bool BlenderSession::draw(int w, int h)
SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
bool session_pause = BlenderSync::get_session_pause(b_scene, background);
if (session_pause == false) {
@@ -974,7 +991,7 @@ bool BlenderSession::draw(int w, int h)
/* draw */
BufferParams buffer_params = BlenderSync::get_buffer_params(
- b_render, b_v3d, b_rv3d, scene->camera, width, height);
+ b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
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 8960c84567e..0412654d3bd 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -846,20 +846,10 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
/* progressive refine */
BL::RenderSettings b_r = b_scene.render();
- params.progressive_refine = (b_engine.is_preview() ||
- get_boolean(cscene, "use_progressive_refine")) &&
- !b_r.use_save_buffers();
-
- if (params.progressive_refine) {
- 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_denoising")) {
- params.progressive_refine = false;
- }
- }
- }
+ params.progressive_refine = b_engine.is_preview() ||
+ get_boolean(cscene, "use_progressive_refine");
+ if (b_r.use_save_buffers())
+ params.progressive_refine = false;
if (background) {
if (params.progressive_refine)
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index f8134ff8b5c..efd4511eb1e 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -95,7 +95,8 @@ class BlenderSync {
BL::Scene &b_scene,
bool background);
static bool get_session_pause(BL::Scene &b_scene, bool background);
- static BufferParams get_buffer_params(BL::RenderSettings &b_render,
+ static BufferParams get_buffer_params(BL::Scene &b_scene,
+ BL::RenderSettings &b_render,
BL::SpaceView3D &b_v3d,
BL::RegionView3D &b_rv3d,
Camera *cam,
diff --git a/intern/cycles/blender/blender_viewport.cpp b/intern/cycles/blender/blender_viewport.cpp
index 73ef5f94720..93e84e28032 100644
--- a/intern/cycles/blender/blender_viewport.cpp
+++ b/intern/cycles/blender/blender_viewport.cpp
@@ -61,6 +61,17 @@ 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;
@@ -72,6 +83,11 @@ 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 f26d0d38115..d2b55358c27 100644
--- a/intern/cycles/blender/blender_viewport.h
+++ b/intern/cycles/blender/blender_viewport.h
@@ -44,11 +44,15 @@ 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