[Bf-blender-cvs] [b455a14252e] cycles_path_guiding: Guiding: Added an option to set the number of training iterations

Sebastian Herholz noreply at git.blender.org
Wed Sep 7 13:22:01 CEST 2022


Commit: b455a14252e82f358326fb3f23d224dbe9cdfecf
Author: Sebastian Herholz
Date:   Wed Sep 7 13:20:52 2022 +0200
Branches: cycles_path_guiding
https://developer.blender.org/rBb455a14252e82f358326fb3f23d224dbe9cdfecf

Guiding: Added an option to set the number of training iterations

After a specific number of training iterations is reached no new training
samples are generated during rendering and the guiding structures
are not updated anymore. From now own the guiding structures are only queried
for sampling, which remove the overhead of collecting the training samples and
updating the structures.

===================================================================

M	intern/cycles/blender/addon/properties.py
M	intern/cycles/blender/addon/ui.py
M	intern/cycles/blender/python.cpp
M	intern/cycles/blender/sync.cpp
M	intern/cycles/device/cpu/device.cpp
M	intern/cycles/device/cpu/device_impl.cpp
M	intern/cycles/integrator/guiding.h
M	intern/cycles/integrator/path_trace.cpp
M	intern/cycles/integrator/path_trace_work_cpu.cpp
M	intern/cycles/kernel/data_template.h
M	intern/cycles/kernel/device/cpu/globals.h
M	intern/cycles/kernel/integrator/guiding.h
M	intern/cycles/kernel/integrator/shade_volume.h
M	intern/cycles/kernel/integrator/surface_shader.h
M	intern/cycles/scene/integrator.cpp
M	intern/cycles/scene/integrator.h
M	intern/cycles/util/guiding.h

===================================================================

diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 22f8ee10017..bc913f4c2c6 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -547,6 +547,16 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
         default=True,
     )
 
+    training_iterations: IntProperty(
+        name="Training Iterations",
+        description="The number of training iterations (i.e., SPPs) used for the guiding structures."
+        "If the this number is reached the guiding structure is used for sampling only which avoids the"
+        " computational over head of the training process."
+        "A value of -1 leads to continuous learning.",
+        min=-1,
+        default=128,
+    )
+
     volume_guiding_probability: FloatProperty(
         name="Volume Guiding Probability",
         description="The probability of guiding a direction inside a volume",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index a8d533e3f5a..cfccbb9edb9 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -351,6 +351,7 @@ class CYCLES_RENDER_PT_sampling_path_guiding(CyclesButtonsPanel, Panel):
         col = layout.column(align=True)
         col.prop(cscene, "use_surface_guiding", text="Surface Guiding")
         col.prop(cscene, "use_volume_guiding", text="Volume Guiding")
+        col.prop(cscene, "training_iterations", text="Training Iterations")
 
 
 class CYCLES_RENDER_PT_sampling_path_guiding_debug(CyclesDebugButtonsPanel, Panel):
diff --git a/intern/cycles/blender/python.cpp b/intern/cycles/blender/python.cpp
index 32fc2496954..9b34b4ea74d 100644
--- a/intern/cycles/blender/python.cpp
+++ b/intern/cycles/blender/python.cpp
@@ -1009,14 +1009,14 @@ void *CCL_python_module_init()
   PyModule_AddStringConstant(mod, "osl_version_string", "unknown");
 #endif
 
-if (ccl::guiding_supported()) {
-  PyModule_AddObject(mod, "with_path_guiding", Py_True);
-  Py_INCREF(Py_True);
-}
-else {
-  PyModule_AddObject(mod, "with_path_guiding", Py_False);
-  Py_INCREF(Py_False);
-}
+  if (ccl::guiding_supported()) {
+    PyModule_AddObject(mod, "with_path_guiding", Py_True);
+    Py_INCREF(Py_True);
+  }
+  else {
+    PyModule_AddObject(mod, "with_path_guiding", Py_False);
+    Py_INCREF(Py_False);
+  }
 
 #ifdef WITH_EMBREE
   PyModule_AddObject(mod, "with_embree", Py_True);
diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp
index 6bd83622cdb..b1e66f2ee3b 100644
--- a/intern/cycles/blender/sync.cpp
+++ b/intern/cycles/blender/sync.cpp
@@ -416,6 +416,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
   integrator->set_use_guiding(get_boolean(cscene, "use_guiding"));
   integrator->set_use_surface_guiding(get_boolean(cscene, "use_surface_guiding"));
   integrator->set_use_volume_guiding(get_boolean(cscene, "use_volume_guiding"));
+  integrator->set_training_iterations(get_int(cscene, "training_iterations"));
 
   if (use_developer_ui) {
     integrator->set_surface_guiding_probability(get_float(cscene, "surface_guiding_probability"));
diff --git a/intern/cycles/device/cpu/device.cpp b/intern/cycles/device/cpu/device.cpp
index 779ff1efae5..9b249063aec 100644
--- a/intern/cycles/device/cpu/device.cpp
+++ b/intern/cycles/device/cpu/device.cpp
@@ -7,8 +7,8 @@
 /* Used for `info.denoisers`. */
 /* TODO(sergey): The denoisers are probably to be moved completely out of the device into their
  * own class. But until then keep API consistent with how it used to work before. */
-#include "util/openimagedenoise.h"
 #include "util/guiding.h"
+#include "util/openimagedenoise.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -28,7 +28,7 @@ void device_cpu_info(vector<DeviceInfo> &devices)
   info.has_osl = true;
   info.has_nanovdb = true;
   info.has_profiling = true;
-  if(guiding_supported()) {
+  if (guiding_supported()) {
     info.has_guiding = true;
   }
   else {
diff --git a/intern/cycles/device/cpu/device_impl.cpp b/intern/cycles/device/cpu/device_impl.cpp
index 642c68df64e..dc2dd51fa74 100644
--- a/intern/cycles/device/cpu/device_impl.cpp
+++ b/intern/cycles/device/cpu/device_impl.cpp
@@ -287,48 +287,50 @@ void *CPUDevice::get_guiding_device() const
 {
 #ifdef WITH_PATH_GUIDING
   if (!guiding_device) {
-#if defined(__ARM_NEON)
+#  if defined(__ARM_NEON)
     guiding_device = make_unique<openpgl::cpp::Device>(PGL_DEVICE_TYPE_CPU_8);
-#else
-    if(system_cpu_support_avx2()) {
+#  else
+    if (system_cpu_support_avx2()) {
       guiding_device = make_unique<openpgl::cpp::Device>(PGL_DEVICE_TYPE_CPU_8);
-    } else if(system_cpu_support_sse41()) {
+    }
+    else if (system_cpu_support_sse41()) {
       guiding_device = make_unique<openpgl::cpp::Device>(PGL_DEVICE_TYPE_CPU_4);
-    } else {
+    }
+    else {
       guiding_device = nullptr;
     }
   }
-#endif
-  return guiding_device.get();
+#  endif
+    return guiding_device.get();
 #else
   return nullptr;
 #endif
-}
+  }
 
-void CPUDevice::get_cpu_kernel_thread_globals(
-    vector<CPUKernelThreadGlobals> &kernel_thread_globals)
-{
-  /* Ensure latest texture info is loaded into kernel globals before returning. */
-  load_texture_info();
-  kernel_thread_globals.clear();
-  void *osl_memory = get_cpu_osl_memory();
-  for (int i = 0; i < info.cpu_threads; i++) {
-    kernel_thread_globals.emplace_back(kernel_globals, osl_memory, profiler);
+  void CPUDevice::get_cpu_kernel_thread_globals(vector<CPUKernelThreadGlobals> &
+                                                kernel_thread_globals)
+  {
+    /* Ensure latest texture info is loaded into kernel globals before returning. */
+    load_texture_info();
+    kernel_thread_globals.clear();
+    void *osl_memory = get_cpu_osl_memory();
+    for (int i = 0; i < info.cpu_threads; i++) {
+      kernel_thread_globals.emplace_back(kernel_globals, osl_memory, profiler);
+    }
   }
-}
 
-void *CPUDevice::get_cpu_osl_memory()
-{
+  void *CPUDevice::get_cpu_osl_memory()
+  {
 #ifdef WITH_OSL
-  return &osl_globals;
+    return &osl_globals;
 #else
   return NULL;
 #endif
-}
+  }
 
-bool CPUDevice::load_kernels(const uint /*kernel_features*/)
-{
-  return true;
-}
+  bool CPUDevice::load_kernels(const uint /*kernel_features*/)
+  {
+    return true;
+  }
 
-CCL_NAMESPACE_END
+  CCL_NAMESPACE_END
diff --git a/intern/cycles/integrator/guiding.h b/intern/cycles/integrator/guiding.h
index 178e05d39f1..a1c6139567c 100644
--- a/intern/cycles/integrator/guiding.h
+++ b/intern/cycles/integrator/guiding.h
@@ -10,12 +10,13 @@ struct GuidingParams {
    * of the guiding field. */
   bool use = false;
   GuidingDistributionType type = GUIDING_TYPE_PARALLAX_AWARE_VMM;
-
+  int training_iterations = 128;
   GuidingParams() = default;
 
   bool modified(const GuidingParams &other) const
   {
-    return !(use == other.use && type == other.type);
+    return !((use == other.use) && (type == other.type) &&
+             (training_iterations == other.training_iterations));
   }
 };
 
diff --git a/intern/cycles/integrator/path_trace.cpp b/intern/cycles/integrator/path_trace.cpp
index 524bb814829..fdcf1490614 100644
--- a/intern/cycles/integrator/path_trace.cpp
+++ b/intern/cycles/integrator/path_trace.cpp
@@ -198,7 +198,8 @@ void PathTrace::render_pipeline(RenderWork render_work)
 
   /* Update the guiding field using the training data/samples collected during the rendering
    * iteration/progression. */
-  if (use_guiding) {
+  const bool train_guiding = device_scene_->data.integrator.train_guiding;
+  if (use_guiding && train_guiding) {
     guiding_update_structures();
   }
 
@@ -1290,8 +1291,14 @@ void PathTrace::set_guiding_params(const GuidingParams &guiding_params, const bo
 
       openpgl::cpp::Device *guiding_device = static_cast<openpgl::cpp::Device *>(
           device_->get_guiding_device());
-      guiding_sample_data_storage_ = make_unique<openpgl::cpp::SampleStorage>();
-      guiding_field_ = make_unique<openpgl::cpp::Field>(guiding_device, field_args);
+      if (guiding_device) {
+        guiding_sample_data_storage_ = make_unique<openpgl::cpp::SampleStorage>();
+        guiding_field_ = make_unique<openpgl::cpp::Field>(guiding_device, field_args);
+      }
+      else {
+        guiding_sample_data_storage_ = nullptr;
+        guiding_field_ = nullptr;
+      }
     }
     else {
       guiding_sample_data_storage_ = nullptr;
@@ -1313,6 +1320,13 @@ void PathTrace::guiding_prepare_structures()
     path_trace_work->guiding_init_kernel_globals(guiding_field_.get(),
                                                  guiding_sample_data_storage_.get());
   }
+  if ((guiding_params_.training_iterations == -1) ||
+      (guiding_field_->GetIteration() < guiding_params_.training_iterations)) {
+    device_scene_->data.integrator.train_guiding = true;
+  }
+  else {
+    device_scene_->data.integrator.train_guiding = false;
+  }
 #endif
 }
 
@@ -1350,7 +1364,7 @@ void PathTrace::guiding_update_structures()
       const size_t num_samples = 1;
       guiding_field_->Update(*guiding_sample_data_storage_, num_samples);
       guiding_update_count++;
-#  ifdef WITH_PATH_GUIDING_DEBUG_PRINT && PATH_GUIDING_DEBUG_VALIDATE
+#  if defined(WITH_PATH_GUIDING_DEBUG_PRINT) && PATH_GUIDING_DEBUG_VALIDATE
       VLOG_WORK << "Field: valid = " << guiding_field_->Validate();
 #  endif
       // if(guiding_update_count<=1)
diff --git a/intern/cycles/integrator/path_trace_work_cpu.cpp b/intern/cycles/integrator/path_trace_work_cpu.cpp
index 83fea8ff193..e212595394c 100644
--- a/intern/cycles/integrator/path_trace_work_cpu.cpp
+++ b/intern/cycles/integrator/path_trace_work_cpu.cpp
@@ -75,15 +75,23 @@ void PathTraceWorkCPU::guiding_init_kernel_globals(void *guiding_field, void *sa
 #  endif
 
 #  if PATH_GUIDING_LEVEL >= 4
-    kernel_thread_globals_[thread_index].opgl_guiding_field = field;
-    if (kernel_thread_globals_[thread_index].opgl_surface_sampling_distribution)
-      delete kernel_thread_globals_[thread_index].opgl_surface_sampling_distribution;
-    kernel_thread_globals_[thread_index].opgl_surface_sampling_distribution =
-        new openpgl::cpp::SurfaceSamplingDistribution(field);
-    if (ke

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list