[Bf-blender-cvs] [49ca810bf30] master: Cycles: enable adaptive sampling for Sobol-Burley

Nathan Vegdahl noreply at git.blender.org
Fri Sep 2 17:52:11 CEST 2022


Commit: 49ca810bf302fdf48e37527d1f8d160fcbd958d2
Author: Nathan Vegdahl
Date:   Fri Sep 2 17:32:34 2022 +0200
Branches: master
https://developer.blender.org/rB49ca810bf302fdf48e37527d1f8d160fcbd958d2

Cycles: enable adaptive sampling for Sobol-Burley

This uses the same sample classification approach as used for PMJ,
because it turns out to also work equally well with Sobol-Burley.

This also implements a fallback (random classification) that should
work "okay" for other samplers, though there are no other samplers
at the moment.

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

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

M	intern/cycles/blender/addon/ui.py
M	intern/cycles/kernel/film/light_passes.h
M	intern/cycles/kernel/sample/pattern.h
M	intern/cycles/scene/integrator.cpp

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

diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 37fecec771b..ee284dd899a 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -296,7 +296,6 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
         row.prop(cscene, "use_animated_seed", text="", icon='TIME')
 
         col = layout.column(align=True)
-        col.active = not (cscene.use_adaptive_sampling and cscene.use_preview_adaptive_sampling)
         col.prop(cscene, "sampling_pattern", text="Pattern")
 
         col = layout.column(align=True)
diff --git a/intern/cycles/kernel/film/light_passes.h b/intern/cycles/kernel/film/light_passes.h
index 5c306e8f088..b45b5305119 100644
--- a/intern/cycles/kernel/film/light_passes.h
+++ b/intern/cycles/kernel/film/light_passes.h
@@ -147,16 +147,16 @@ ccl_device void film_write_adaptive_buffer(KernelGlobals kg,
                                            const Spectrum contribution,
                                            ccl_global float *ccl_restrict buffer)
 {
-  /* Adaptive Sampling. Fill the additional buffer with the odd samples and calculate our stopping
-   * criteria. This is the heuristic from "A hierarchical automatic stopping condition for Monte
-   * Carlo global illumination" except that here it is applied per pixel and not in hierarchical
-   * tiles. */
+  /* Adaptive Sampling. Fill the additional buffer with only one half of the samples and
+   * calculate our stopping criteria. This is the heuristic from "A hierarchical automatic
+   * stopping condition for Monte Carlo global illumination" except that here it is applied
+   * per pixel and not in hierarchical tiles. */
 
   if (kernel_data.film.pass_adaptive_aux_buffer == PASS_UNUSED) {
     return;
   }
 
-  if (sample_is_even(kernel_data.integrator.sampling_pattern, sample)) {
+  if (sample_is_class_A(kernel_data.integrator.sampling_pattern, sample)) {
     const float3 contribution_rgb = spectrum_to_rgb(contribution);
 
     film_write_pass_float4(buffer + kernel_data.film.pass_adaptive_aux_buffer,
diff --git a/intern/cycles/kernel/sample/pattern.h b/intern/cycles/kernel/sample/pattern.h
index 6477e29fa40..fa48cc216af 100644
--- a/intern/cycles/kernel/sample/pattern.h
+++ b/intern/cycles/kernel/sample/pattern.h
@@ -90,18 +90,31 @@ ccl_device_inline uint path_rng_hash_init(KernelGlobals kg,
   return rng_hash;
 }
 
-ccl_device_inline bool sample_is_even(int pattern, int sample)
+/**
+ * Splits samples into two different classes, A and B, which can be
+ * compared for variance estimation.
+ */
+ccl_device_inline bool sample_is_class_A(int pattern, int sample)
 {
-  if (pattern == SAMPLING_PATTERN_PMJ) {
-    /* See Section 10.2.1, "Progressive Multi-Jittered Sample Sequences", Christensen et al.
-     * We can use this to get divide sample sequence into two classes for easier variance
-     * estimation. */
-    return popcount(uint(sample) & 0xaaaaaaaa) & 1;
-  }
-  else {
-    /* TODO(Stefan): Are there reliable ways of dividing Sobol-Burley into two classes? */
-    return sample & 0x1;
+#if 0
+  if (!(pattern == SAMPLING_PATTERN_PMJ || pattern == SAMPLING_PATTERN_SOBOL_BURLEY)) {
+    /* Fallback: assign samples randomly.
+     * This is guaranteed to work "okay" for any sampler, but isn't good.
+     * (Note: the seed constant is just a random number to guard against
+     * possible interactions with other uses of the hash. There's nothing
+     * special about it.)
+     */
+    return hash_hp_seeded_uint(sample, 0xa771f873) & 1;
   }
-}
+#endif
 
+  /* This follows the approach from section 10.2.1 of "Progressive
+   * Multi-Jittered Sample Sequences" by Christensen et al., but
+   * implemented with efficient bit-fiddling.
+   *
+   * This approach also turns out to work equally well with Sobol-Burley
+   * (see https://developer.blender.org/D15746#429471).
+   */
+  return popcount(uint(sample) & 0xaaaaaaaa) & 1;
+}
 CCL_NAMESPACE_END
diff --git a/intern/cycles/scene/integrator.cpp b/intern/cycles/scene/integrator.cpp
index 86a2c9571c6..e9cd753854f 100644
--- a/intern/cycles/scene/integrator.cpp
+++ b/intern/cycles/scene/integrator.cpp
@@ -217,9 +217,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
                                            FLT_MAX :
                                            sample_clamp_indirect * 3.0f;
 
-  /* Adaptive sampling requires PMJ, see sample_is_even. */
-  kintegrator->sampling_pattern = (use_adaptive_sampling) ? SAMPLING_PATTERN_PMJ :
-                                                            sampling_pattern;
+  kintegrator->sampling_pattern = sampling_pattern;
   kintegrator->scrambling_distance = scrambling_distance;
 
   if (light_sampling_threshold > 0.0f) {



More information about the Bf-blender-cvs mailing list