[Bf-blender-cvs] [b0cc8e8ddec] master: Cycles: switch from pretabulated 2D PMJ02 to pretabulated 4D Sobol

Nathan Vegdahl noreply at git.blender.org
Wed Dec 14 17:51:04 CET 2022


Commit: b0cc8e8ddec3f1771b69234860b40511be975039
Author: Nathan Vegdahl
Date:   Tue Dec 13 19:14:29 2022 +0100
Branches: master
https://developer.blender.org/rBb0cc8e8ddec3f1771b69234860b40511be975039

Cycles: switch from pretabulated 2D PMJ02 to pretabulated 4D Sobol

The first two dimensions of scrambled, shuffled Sobol and shuffled PMJ02 are
equivalent, so this makes no real difference for the first two dimensions.
But Sobol allows us to naturally extend to more dimensions.

Pretabulated Sobol is now always used, and the sampling pattern settings is now
only available as a debug option.

This in turn allows the following two things (also implemented):

* Use proper 3D samples for combined lens + motion blur sampling. This
  notably reduces the noise on objects that are simultaneously out-of-focus
  and motion blurred.
* Use proper 3D samples for combined light selection + light sampling.
  Cycles was already doing something clever here with 2D samples, but using
  3D samples is more straightforward and avoids overloading one of the
  dimensions.

In the future this will also allow for proper sampling of e.g. volumetric
light sources and other things that may need three or four dimensions.

Differential Revision: https://developer.blender.org/D16443

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

M	intern/cycles/blender/addon/properties.py
M	intern/cycles/blender/addon/ui.py
M	intern/cycles/blender/addon/version_update.py
M	intern/cycles/blender/sync.cpp
M	intern/cycles/kernel/CMakeLists.txt
M	intern/cycles/kernel/data_arrays.h
M	intern/cycles/kernel/data_template.h
M	intern/cycles/kernel/integrator/init_from_camera.h
M	intern/cycles/kernel/integrator/path_state.h
M	intern/cycles/kernel/integrator/shade_surface.h
M	intern/cycles/kernel/integrator/shade_volume.h
M	intern/cycles/kernel/light/distribution.h
M	intern/cycles/kernel/light/sample.h
M	intern/cycles/kernel/light/tree.h
D	intern/cycles/kernel/sample/jitter.h
M	intern/cycles/kernel/sample/pattern.h
A	intern/cycles/kernel/sample/tabulated_sobol.h
M	intern/cycles/kernel/types.h
M	intern/cycles/scene/CMakeLists.txt
M	intern/cycles/scene/integrator.cpp
D	intern/cycles/scene/jitter.cpp
D	intern/cycles/scene/jitter.h
A	intern/cycles/scene/tabulated_sobol.cpp
A	intern/cycles/scene/tabulated_sobol.h

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

diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 2da763b9eb1..eff6384c85e 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -82,8 +82,8 @@ enum_use_layer_samples = (
 )
 
 enum_sampling_pattern = (
-    ('SOBOL', "Sobol-Burley", "Use Sobol-Burley random sampling pattern", 0),
-    ('PROGRESSIVE_MULTI_JITTER', "Progressive Multi-Jitter", "Use Progressive Multi-Jitter random sampling pattern", 1),
+    ('SOBOL_BURLEY', "Sobol-Burley", "Use on-the-fly computed Owen-scrambled Sobol for random sampling", 0),
+    ('TABULATED_SOBOL', "Tabulated Sobol", "Use precomputed tables of Owen-scrambled Sobol for random sampling", 1),
 )
 
 enum_emission_sampling = (
@@ -412,9 +412,9 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
 
     sampling_pattern: EnumProperty(
         name="Sampling Pattern",
-        description="Random sampling pattern used by the integrator. When adaptive sampling is enabled, Progressive Multi-Jitter is always used instead of Sobol-Burley",
+        description="Random sampling pattern used by the integrator",
         items=enum_sampling_pattern,
-        default='PROGRESSIVE_MULTI_JITTER',
+        default='TABULATED_SOBOL',
     )
 
     scrambling_distance: FloatProperty(
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index c3477ae0284..4746790aae8 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -364,16 +364,13 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
         row.prop(cscene, "seed")
         row.prop(cscene, "use_animated_seed", text="", icon='TIME')
 
-        col = layout.column(align=True)
-        col.prop(cscene, "sampling_pattern", text="Pattern")
-
         col = layout.column(align=True)
         col.prop(cscene, "sample_offset")
 
         layout.separator()
 
         heading = layout.column(align=True, heading="Scrambling Distance")
-        heading.active = cscene.sampling_pattern != 'SOBOL'
+        heading.active = cscene.sampling_pattern != 'TABULATED_SOBOL'
         heading.prop(cscene, "auto_scrambling_distance", text="Automatic")
         heading.prop(cscene, "preview_scrambling_distance", text="Viewport")
         heading.prop(cscene, "scrambling_distance", text="Multiplier")
@@ -396,11 +393,22 @@ class CYCLES_RENDER_PT_sampling_lights(CyclesButtonsPanel, Panel):
     bl_parent_id = "CYCLES_RENDER_PT_sampling"
     bl_options = {'DEFAULT_CLOSED'}
 
-    def draw_header(self, context):
+    def draw(self, context):
         layout = self.layout
         scene = context.scene
         cscene = scene.cycles
 
+        col.prop(cscene, "use_light_tree")
+        sub = col.row()
+        sub.prop(cscene, "light_sampling_threshold", text="Light Threshold")
+        sub.active = not cscene.use_light_tree
+
+
+class CYCLES_RENDER_PT_sampling_debug(CyclesDebugButtonsPanel, Panel):
+    bl_label = "Debug"
+    bl_parent_id = "CYCLES_RENDER_PT_sampling"
+    bl_options = {'DEFAULT_CLOSED'}
+
     def draw(self, context):
         layout = self.layout
         layout.use_property_split = True
@@ -410,10 +418,7 @@ class CYCLES_RENDER_PT_sampling_lights(CyclesButtonsPanel, Panel):
         cscene = scene.cycles
 
         col = layout.column(align=True)
-        col.prop(cscene, "use_light_tree")
-        sub = col.row()
-        sub.prop(cscene, "light_sampling_threshold", text="Light Threshold")
-        sub.active = not cscene.use_light_tree
+        col.prop(cscene, "sampling_pattern", text="Pattern")
 
 
 class CYCLES_RENDER_PT_subdivision(CyclesButtonsPanel, Panel):
@@ -2391,6 +2396,7 @@ classes = (
     CYCLES_RENDER_PT_sampling_path_guiding_debug,
     CYCLES_RENDER_PT_sampling_lights,
     CYCLES_RENDER_PT_sampling_advanced,
+    CYCLES_RENDER_PT_sampling_debug,
     CYCLES_RENDER_PT_light_paths,
     CYCLES_RENDER_PT_light_paths_max_bounces,
     CYCLES_RENDER_PT_light_paths_clamping,
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index 7f81ac96309..56d921e49cd 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -228,7 +228,7 @@ def do_versions(self):
                     cscene.use_preview_denoising = False
                 if not cscene.is_property_set("sampling_pattern") or \
                    cscene.get('sampling_pattern') >= 2:
-                    cscene.sampling_pattern = 'PROGRESSIVE_MULTI_JITTER'
+                    cscene.sampling_pattern = 'TABULATED_SOBOL'
 
                 # Removal of square samples.
                 cscene = scene.cycles
diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp
index f8be1b210b8..d87d094dc56 100644
--- a/intern/cycles/blender/sync.cpp
+++ b/intern/cycles/blender/sync.cpp
@@ -357,7 +357,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
   }
 
   SamplingPattern sampling_pattern = (SamplingPattern)get_enum(
-      cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_PMJ);
+      cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_TABULATED_SOBOL);
   integrator->set_sampling_pattern(sampling_pattern);
 
   int samples = 1;
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 9dc343f597d..22c52a5802f 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -299,12 +299,12 @@ set(SRC_KERNEL_LIGHT_HEADERS
 )
 
 set(SRC_KERNEL_SAMPLE_HEADERS
-  sample/jitter.h
   sample/lcg.h
   sample/mapping.h
   sample/mis.h
   sample/pattern.h
   sample/sobol_burley.h
+  sample/tabulated_sobol.h
   sample/util.h
 )
 
diff --git a/intern/cycles/kernel/data_arrays.h b/intern/cycles/kernel/data_arrays.h
index 6914a4642e9..633678fe055 100644
--- a/intern/cycles/kernel/data_arrays.h
+++ b/intern/cycles/kernel/data_arrays.h
@@ -77,7 +77,7 @@ KERNEL_DATA_ARRAY(KernelShader, shaders)
 /* lookup tables */
 KERNEL_DATA_ARRAY(float, lookup_table)
 
-/* PMJ sample pattern */
+/* tabulated Sobol sample pattern */
 KERNEL_DATA_ARRAY(float, sample_pattern_lut)
 
 /* image textures */
diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h
index 06df7fe1e62..af7a6d2ef41 100644
--- a/intern/cycles/kernel/data_template.h
+++ b/intern/cycles/kernel/data_template.h
@@ -179,7 +179,7 @@ KERNEL_STRUCT_MEMBER(integrator, float, sample_clamp_indirect)
 KERNEL_STRUCT_MEMBER(integrator, int, use_caustics)
 /* Sampling pattern. */
 KERNEL_STRUCT_MEMBER(integrator, int, sampling_pattern)
-KERNEL_STRUCT_MEMBER(integrator, int, pmj_sequence_size)
+KERNEL_STRUCT_MEMBER(integrator, int, tabulated_sobol_sequence_size)
 KERNEL_STRUCT_MEMBER(integrator, float, scrambling_distance)
 /* Volume render. */
 KERNEL_STRUCT_MEMBER(integrator, int, use_volumes)
diff --git a/intern/cycles/kernel/integrator/init_from_camera.h b/intern/cycles/kernel/integrator/init_from_camera.h
index 8df3e1b9fb3..e8b2224bce6 100644
--- a/intern/cycles/kernel/integrator/init_from_camera.h
+++ b/intern/cycles/kernel/integrator/init_from_camera.h
@@ -26,18 +26,22 @@ ccl_device_inline void integrate_camera_sample(KernelGlobals kg,
   const float2 rand_filter = (sample == 0) ? make_float2(0.5f, 0.5f) :
                                              path_rng_2D(kg, rng_hash, sample, PRNG_FILTER);
 
-  /* Depth of field sampling. */
-  const float2 rand_lens = (kernel_data.cam.aperturesize > 0.0f) ?
-                               path_rng_2D(kg, rng_hash, sample, PRNG_LENS) :
-                               zero_float2();
-
-  /* Motion blur time sampling. */
-  const float rand_time = (kernel_data.cam.shuttertime != -1.0f) ?
-                              path_rng_1D(kg, rng_hash, sample, PRNG_TIME) :
-                              0.0f;
+  /* Motion blur (time) and depth of field (lens) sampling. (time, lens_x, lens_y) */
+  const float3 rand_time_lens = (kernel_data.cam.shuttertime != -1.0f ||
+                                 kernel_data.cam.aperturesize > 0.0f) ?
+                                    path_rng_3D(kg, rng_hash, sample, PRNG_LENS_TIME) :
+                                    zero_float3();
 
   /* Generate camera ray. */
-  camera_sample(kg, x, y, rand_filter.x, rand_filter.y, rand_lens.x, rand_lens.y, rand_time, ray);
+  camera_sample(kg,
+                x,
+                y,
+                rand_filter.x,
+                rand_filter.y,
+                rand_time_lens.y,
+                rand_time_lens.z,
+                rand_time_lens.x,
+                ray);
 }
 
 /* Return false to indicate that this pixel is finished.
diff --git a/intern/cycles/kernel/integrator/path_state.h b/intern/cycles/kernel/integrator/path_state.h
index 9d8ecdc47b4..8d90a9f6067 100644
--- a/intern/cycles/kernel/integrator/path_state.h
+++ b/intern/cycles/kernel/integrator/path_state.h
@@ -336,6 +336,14 @@ ccl_device_inline float2 path_state_rng_2D(KernelGlobals kg,
       kg, rng_state->rng_hash, rng_state->sample, rng_state->rng_offset + dimension);
 }
 
+ccl_device_inline float3 path_state_rng_3D(KernelGlobals kg,
+                                           ccl_private const RNGState *rng_state,
+                                           const int dimension)
+{
+  return path_rng_3D(
+      kg, rng_state->rng_hash, rng_state->sample, rng_state->rng_offset + dimension);
+}
+
 ccl_device_inline float path_branched_rng_1D(KernelGlobals kg,
                                              ccl_private const RNGState *rng_state,
                                              const int branch,
@@ -360,6 +368,18 @@ ccl_device_inline float2 path_branched_rng_2D(KernelGlobals kg,
                      rng_state->rng_offset + dimension);
 }
 
+ccl_device_inline float3 path_branched_rng_3D(KernelGlobals kg,
+                                              ccl_private const RNGState *rng_state,
+                                              const int branch,
+                                              const int num_branches,
+                                              const int dimension)
+{
+  return path_rng_3D(kg,
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list