[Bf-blender-cvs] [f4641a35e52] cycles_path_guiding: Cycles-X: Integration of path guiding using Intel's Open Path Guidign Library (Open PGL)

Sebastian Herholz noreply at git.blender.org
Fri Jun 24 13:09:15 CEST 2022


Commit: f4641a35e5235c72ef63f871e73a97bf1d269a77
Author: Sebastian Herholz
Date:   Thu Jun 23 11:30:51 2022 +0200
Branches: cycles_path_guiding
https://developer.blender.org/rBf4641a35e5235c72ef63f871e73a97bf1d269a77

Cycles-X: Integration of path guiding using Intel's Open Path Guidign Library (Open PGL)

This patch adds path guiding features into Cycles
by integrating IntelĀ®'s Open path guiding library
(Open PGL: https://github.com/OpenPathGuidingLibrary/openpgl).

The current implementation supports guiding directional sampling
decisions on surfaces, when the material contains a least one diffuse component,
and in volumes, with isotropic and anisotropic Henyey-Greenstein phase functions.

On surfaces, the guided sampling decision is proportional to the product of
the incident radiance and the normal-oriented cosine lobe and in volumes it
is proportional to the product of the incident radiance and the phase function.

The incident radiance field of a scene is learned and updated during rendering
after each per-frame rendering iteration/progression.

At the moment, path guiding is only supported by Cycles
CPU backend. Support for GPU backends will be added in
future versions of Open PGL.

To build Blender/Cycles with path guiding support, one only needs to enable
the CMake option `WITH_PATH_GUIDING`.

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

M	intern/cycles/blender/addon/properties.py
M	intern/cycles/blender/addon/ui.py
M	intern/cycles/blender/sync.cpp
M	intern/cycles/device/cpu/device_impl.cpp
M	intern/cycles/device/cpu/device_impl.h
M	intern/cycles/device/cpu/kernel_thread_globals.cpp
M	intern/cycles/device/device.h
A	intern/cycles/integrator/guiding.h
M	intern/cycles/integrator/path_trace.cpp
M	intern/cycles/integrator/path_trace.h
M	intern/cycles/integrator/path_trace_work.h
M	intern/cycles/integrator/path_trace_work_cpu.cpp
M	intern/cycles/integrator/path_trace_work_cpu.h
M	intern/cycles/integrator/render_scheduler.cpp
M	intern/cycles/kernel/closure/bsdf.h
M	intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h
M	intern/cycles/kernel/closure/bsdf_hair.h
M	intern/cycles/kernel/closure/bsdf_hair_principled.h
M	intern/cycles/kernel/closure/bsdf_microfacet.h
M	intern/cycles/kernel/closure/bsdf_microfacet_multi.h
M	intern/cycles/kernel/closure/bsdf_phong_ramp.h
M	intern/cycles/kernel/closure/bsdf_reflection.h
M	intern/cycles/kernel/closure/bsdf_refraction.h
M	intern/cycles/kernel/device/cpu/globals.h
M	intern/cycles/kernel/integrator/intersect_closest.h
M	intern/cycles/kernel/integrator/path_state.h
M	intern/cycles/kernel/integrator/shade_background.h
M	intern/cycles/kernel/integrator/shade_light.h
M	intern/cycles/kernel/integrator/shade_shadow.h
M	intern/cycles/kernel/integrator/shade_surface.h
M	intern/cycles/kernel/integrator/shade_volume.h
M	intern/cycles/kernel/integrator/shader_eval.h
M	intern/cycles/kernel/integrator/shadow_state_template.h
M	intern/cycles/kernel/integrator/state.h
M	intern/cycles/kernel/integrator/state_template.h
M	intern/cycles/kernel/integrator/state_util.h
M	intern/cycles/kernel/integrator/subsurface.h
M	intern/cycles/kernel/integrator/subsurface_disk.h
M	intern/cycles/kernel/integrator/subsurface_random_walk.h
M	intern/cycles/kernel/svm/closure.h
M	intern/cycles/kernel/types.h
M	intern/cycles/scene/film.cpp
M	intern/cycles/scene/integrator.cpp
M	intern/cycles/scene/integrator.h
M	intern/cycles/scene/pass.cpp
M	intern/cycles/scene/scene.cpp
M	intern/cycles/scene/scene.h
M	intern/cycles/session/session.cpp

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

diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index b444a806f8d..13b1f8fe29e 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -178,6 +178,12 @@ enum_view3d_shading_render_pass = (
     ('SAMPLE_COUNT', "Sample Count", "Per-pixel number of samples"),
 )
 
+enum_guiding_distribution = (
+    ('PAVMM', "Paralax-Aware VMM", "Use Parallax-aware von Mises-Fisher models as directional distribution", 0),
+    ('DQT', "Directional Quad Tree", "Use Directional Quad Trees as directional distribution", 1),
+    ('VMM', "VMM", "Use von Mises-Fisher models as directional distribution", 2),
+)
+
 
 def enum_openimagedenoise_denoiser(self, context):
     import _cycles
@@ -506,6 +512,57 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
         default=1.0,
     )
 
+    guiding: BoolProperty(
+        name="Guiding",
+        description="Use path guiding for sampling paths",
+        default=True,
+    )
+
+    guiding_distribution_type: EnumProperty(
+        name="Guiding Distribution Type",
+        description="The type of the used representation for the guiding distribution",
+        items=enum_guiding_distribution,
+        default='PAVMM',
+    )
+
+    surface_guiding: BoolProperty(
+        name="Surface Guiding",
+        description="Use guiding when sampling directions on a surface",
+        default=True,
+    )
+
+    surface_guiding_probability: FloatProperty(
+        name="Surface Guiding Prob.",
+        description="The probability of guiding a direction on a surface",
+        min=0.0, max=1.0,
+        default=0.5,
+    )
+
+    volume_guiding: BoolProperty(
+        name="Volume Guiding",
+        description="Use guiding when sampling directions inside a volume",
+        default=True,
+    )
+
+    volume_guiding_probability: FloatProperty(
+        name="Volume Guiding Prob.",
+        description="The probability of guiding a direction inside a volume",
+        min=0.0, max=1.0,
+        default=0.5,
+    )
+
+    guide_direct_light: BoolProperty(
+        name="Guide Direct Light",
+        description="Consider the contribution of directly visible light sources during guiding",
+        default=True,
+    )
+
+    use_mis_weights: BoolProperty(
+        name="Use MIS Weights",
+        description="Use the MIS weight to weight the contribution of directly visible light sources during guiding",
+        default=True,
+    )
+
     max_bounces: IntProperty(
         name="Max Bounces",
         description="Total maximum number of bounces",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 88be546746d..aef86d8c019 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -458,6 +458,41 @@ class CYCLES_RENDER_PT_light_paths_caustics(CyclesButtonsPanel, Panel):
         col.prop(cscene, "caustics_refractive", text="Refractive")
 
 
+class CYCLES_RENDER_PT_light_paths_guiding(CyclesButtonsPanel, Panel):
+    bl_label = "Guiding"
+    bl_parent_id = "CYCLES_RENDER_PT_light_paths"
+
+    def draw_header(self, context):
+        scene = context.scene
+        cscene = scene.cycles
+
+        if cscene.device != 'CPU':
+            return
+
+        self.layout.prop(cscene, "guiding", text="")
+
+    def draw(self, context):
+        scene = context.scene
+        cscene = scene.cycles
+
+        if cscene.device != 'CPU':
+            return
+
+        layout = self.layout
+        layout.use_property_split = True
+        layout.use_property_decorate = False
+        layout.active = cscene.guiding
+
+        col = layout.column(align=True)
+        col.prop(cscene, "guiding_distribution_type", text="Distribution Type")
+        col.prop(cscene, "surface_guiding", text="Surface Guiding")
+        col.prop(cscene, "surface_guiding_probability", text="Surface Guiding Probability")
+        col.prop(cscene, "volume_guiding", text="Volume Guiding")
+        col.prop(cscene, "volume_guiding_probability", text="Volume Guiding Probability")
+        col.prop(cscene, "guide_direct_light", text="Guide Direct Light")
+        col.prop(cscene, "use_mis_weights", text="Use MIS Weights")
+
+
 class CYCLES_RENDER_PT_light_paths_fast_gi(CyclesButtonsPanel, Panel):
     bl_label = "Fast GI Approximation"
     bl_options = {'DEFAULT_CLOSED'}
@@ -2271,6 +2306,7 @@ classes = (
     CYCLES_RENDER_PT_sampling_advanced,
     CYCLES_RENDER_PT_light_paths,
     CYCLES_RENDER_PT_light_paths_max_bounces,
+    CYCLES_RENDER_PT_light_paths_guiding,
     CYCLES_RENDER_PT_light_paths_clamping,
     CYCLES_RENDER_PT_light_paths_caustics,
     CYCLES_RENDER_PT_light_paths_fast_gi,
diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp
index 63e9e1e0e68..c81d205c6e4 100644
--- a/intern/cycles/blender/sync.cpp
+++ b/intern/cycles/blender/sync.cpp
@@ -412,6 +412,19 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
   integrator->set_direct_light_sampling_type(direct_light_sampling_type);
 #endif
 
+#ifdef __PATH_GUIDING__
+  integrator->set_guiding(get_boolean(cscene, "guiding"));
+  integrator->set_surface_guiding(get_boolean(cscene, "surface_guiding"));
+  integrator->set_surface_guiding_probability(get_float(cscene, "surface_guiding_probability"));
+  integrator->set_volume_guiding(get_boolean(cscene, "volume_guiding"));
+  integrator->set_volume_guiding_probability(get_float(cscene, "volume_guiding_probability"));
+  integrator->set_guide_direct_light(get_boolean(cscene, "guide_direct_light"));
+  integrator->set_use_mis_weights(get_boolean(cscene, "use_mis_weights"));
+  GuidingDistributionType guiding_distribution_type = (GuidingDistributionType)get_enum(
+      cscene, "guiding_distribution_type", GUIDING_NUM_TYPES, GUIDING_TYPE_PAVMM);
+  integrator->set_guiding_distribution_type(guiding_distribution_type);
+#endif
+
   const DenoiseParams denoise_params = get_denoise_params(b_scene, b_view_layer, background);
   integrator->set_use_denoise(denoise_params.use);
 
@@ -724,6 +737,17 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
     pass_add(scene, PASS_DENOISING_DEPTH, "Denoising Depth", PassMode::NOISY);
   }
 
+#if defined(__PATH_GUIDING__) && defined(PATH_GUIDING_DEBUG_PASS)
+  b_engine.add_pass("OpenPGL Color", 3, "RGB", b_view_layer.name().c_str());
+  pass_add(scene, PASS_OPGL_COLOR, "OpenPGL Color", PassMode::NOISY);
+
+  b_engine.add_pass("OpenPGL Guiding Prob", 1, "X", b_view_layer.name().c_str());
+  pass_add(scene, PASS_OPGL_GUIDING_PROB, "OpenPGL Guiding Prob", PassMode::NOISY);
+
+  b_engine.add_pass("OpenPGL Avg Roughness", 1, "X", b_view_layer.name().c_str());
+  pass_add(scene, PASS_OPGL_AVG_ROUGHNESS, "OpenPGL Avg Roughness", PassMode::NOISY);
+#endif
+
   /* Custom AOV passes. */
   BL::ViewLayer::aovs_iterator b_aov_iter;
   for (b_view_layer.aovs.begin(b_aov_iter); b_aov_iter != b_view_layer.aovs.end(); ++b_aov_iter) {
diff --git a/intern/cycles/device/cpu/device_impl.cpp b/intern/cycles/device/cpu/device_impl.cpp
index d4f0532aa5e..7e3b748303c 100644
--- a/intern/cycles/device/cpu/device_impl.cpp
+++ b/intern/cycles/device/cpu/device_impl.cpp
@@ -17,6 +17,10 @@
 #  include <embree3/rtcore.h>
 #endif
 
+#ifdef __PATH_GUIDING__
+#  include <openpgl/cpp/OpenPGL.h>
+#endif
+
 #include "device/cpu/kernel.h"
 #include "device/cpu/kernel_thread_globals.h"
 
@@ -69,6 +73,11 @@ CPUDevice::CPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_
   embree_device = rtcNewDevice("verbose=0");
 #endif
   need_texture_info = false;
+
+#ifdef __PATH_GUIDING__
+  // TODO(sherholz): we need to replace this with PGL_DEVICE_TYPE_CPU_AUTO
+  openpgl_device = new openpgl::cpp::Device(PGL_DEVICE_TYPE_CPU_4);
+#endif
 }
 
 CPUDevice::~CPUDevice()
@@ -77,6 +86,11 @@ CPUDevice::~CPUDevice()
   rtcReleaseDevice(embree_device);
 #endif
 
+#ifdef __PATH_GUIDING__
+  if (openpgl_device)
+    delete openpgl_device;
+#endif
+
   texture_info.free();
 }
 
@@ -279,12 +293,21 @@ void CPUDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
     Device::build_bvh(bvh, progress, refit);
 }
 
+#if defined(__PATH_GUIDING__)
+void *CPUDevice::create_guiding_field(void *guiding_field_args_) const
+{
+  PGLFieldArguments guiding_field_args = *(static_cast<PGLFieldArguments *>(guiding_field_args_));
+  openpgl::cpp::Field *guiding_field_ptr = new openpgl::cpp::Field(openpgl_device,
+                                                                   guiding_field_args);
+  return static_cast<void *>(guiding_field_ptr);
+}
+#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++) {
diff --git a/intern/cycles/device/cpu/device_impl.h b/intern/cycles/device/cpu/device_impl.h
index 5c1f3cc6ce5..8611a49ff6b 100644
--- a/intern/cycles/device/cpu/device_impl.h
+++ b/intern/cycles/device/cpu/device_impl.h
@@ -43,6 +43,9 @@ class CPUDevice : public Device {
   RTCScene embree_scene = NULL;
   RTCDevice embree_device;
 #endif
+#ifdef __PATH_GUIDING__
+  openpgl::cpp::Device *openpgl_device = NULL;
+#endif
 
   CPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_);
   ~CPUDevice();
@@ -73,6 +76,10 @@ class CPUDevice : public Device {
 
   void build_bvh(BVH *bvh, Progress &progress, bool refit) override;
 
+#ifdef __PATH_GUIDING__
+  void *create_guiding_field(void *guiding_field_args) const override;
+#endif
+
   virtual void get_cpu_kernel_thread_globals(
       vector<CPUKernelThreadGlobals> &kernel_thread_globals) override;
   virtual void *get_cpu_osl_memory() override;
diff --git a/intern/cycles/device/cpu/kernel_thread_globals.cpp b/intern/cycles/device/cpu/kernel_thread_globals.cpp
index 89545399602..d1ea603dcfb 100644
--- a/intern/cycles/device/cpu/kernel_thread_globals.cpp
+++ b/intern/cycles/device/cpu/kernel_thread_globals.cpp
@@ -24,6 +24,18 @@ CPUKernelThreadGlobals::CPUKernelThrea

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list