[Bf-blender-cvs] [853b4a6cf95] soc-2022-many-lights-sampling: Fix wrong MIS weights when culling nodes for transmission

Brecht Van Lommel noreply at git.blender.org
Fri Oct 14 21:07:50 CEST 2022


Commit: 853b4a6cf9501e37a96610252c02051ee9d12b9e
Author: Brecht Van Lommel
Date:   Fri Oct 14 20:29:29 2022 +0200
Branches: soc-2022-many-lights-sampling
https://developer.blender.org/rB853b4a6cf9501e37a96610252c02051ee9d12b9e

Fix wrong MIS weights when culling nodes for transmission

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

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/light_tree.h
M	intern/cycles/kernel/types.h

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

diff --git a/intern/cycles/kernel/integrator/path_state.h b/intern/cycles/kernel/integrator/path_state.h
index dbc6fc5a883..57d7c08cbdf 100644
--- a/intern/cycles/kernel/integrator/path_state.h
+++ b/intern/cycles/kernel/integrator/path_state.h
@@ -84,7 +84,10 @@ ccl_device_inline void path_state_init_integrator(KernelGlobals kg,
 #endif
 }
 
-ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state, int label)
+ccl_device_inline void path_state_next(KernelGlobals kg,
+                                       IntegratorState state,
+                                       const int label,
+                                       const int shader_flag)
 {
   uint32_t flag = INTEGRATOR_STATE(state, path, flag);
 
@@ -113,7 +116,7 @@ ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state,
     flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
   }
 
-  flag &= ~(PATH_RAY_ALL_VISIBILITY | PATH_RAY_MIS_SKIP);
+  flag &= ~(PATH_RAY_ALL_VISIBILITY | PATH_RAY_MIS_SKIP | PATH_RAY_MIS_HAD_TRANSMISSION);
 
 #ifdef __VOLUME__
   if (label & LABEL_VOLUME_SCATTER) {
@@ -181,6 +184,11 @@ ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state,
       flag |= PATH_RAY_GLOSSY | PATH_RAY_SINGULAR | PATH_RAY_MIS_SKIP;
     }
 
+    /* Flag for consistent MIS weights with light tree. */
+    if (shader_flag & SD_BSDF_HAS_TRANSMISSION) {
+      flag |= PATH_RAY_MIS_HAD_TRANSMISSION;
+    }
+
     /* Render pass categories. */
     if (!(flag & PATH_RAY_ANY_PASS) && !(flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
       flag |= PATH_RAY_SURFACE_PASS;
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index 5d707cfe9ac..47a2c4cce13 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -472,7 +472,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
         unguided_bsdf_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf));
   }
 
-  path_state_next(kg, state, label);
+  path_state_next(kg, state, label, sd->flag);
 
   guiding_record_surface_bounce(kg,
                                 state,
diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h
index a8324cda2dc..9eb05ea8889 100644
--- a/intern/cycles/kernel/integrator/shade_volume.h
+++ b/intern/cycles/kernel/integrator/shade_volume.h
@@ -952,7 +952,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
   INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf(
       unguided_phase_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf));
 
-  path_state_next(kg, state, label);
+  path_state_next(kg, state, label, sd->flag);
   return true;
 }
 
diff --git a/intern/cycles/kernel/light/light_tree.h b/intern/cycles/kernel/light/light_tree.h
index 76c98de4759..85069cd5118 100644
--- a/intern/cycles/kernel/light/light_tree.h
+++ b/intern/cycles/kernel/light/light_tree.h
@@ -569,9 +569,7 @@ ccl_device float light_tree_pdf(KernelGlobals kg,
                                 const int path_flag,
                                 const int prim)
 {
-  /* TODO: this is wrong, needs to also be true if the previous bounce had a transmission BSDF but
-   * sampled a reflection BSDF. */
-  const bool has_transmission = (path_flag & PATH_RAY_TRANSMIT);
+  const bool has_transmission = (path_flag & PATH_RAY_MIS_HAD_TRANSMISSION);
   float distant_light_importance = light_tree_distant_light_importance(
       kg, N, has_transmission, kernel_data.integrator.num_distant_lights);
   float light_tree_importance = 0.0f;
@@ -712,9 +710,7 @@ ccl_device float light_tree_pdf(KernelGlobals kg,
 ccl_device float distant_lights_pdf(
     KernelGlobals kg, const float3 P, const float3 N, const int path_flag, const int prim)
 {
-  /* TODO: this is wrong, needs to also be true if the previous bounce had a transmission BSDF but
-   * sampled a reflection BSDF. */
-  const bool has_transmission = (path_flag & PATH_RAY_TRANSMIT);
+  const bool has_transmission = (path_flag & PATH_RAY_MIS_HAD_TRANSMISSION);
   float distant_light_importance = light_tree_distant_light_importance(
       kg, N, has_transmission, kernel_data.integrator.num_distant_lights);
   float light_tree_importance = 0.0f;
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index df1829b7a59..9efaa5d515c 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -204,21 +204,26 @@ enum PathRayFlag : uint32_t {
   PATH_RAY_SHADOW_TRANSPARENT = (1U << 9U),
   PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE | PATH_RAY_SHADOW_TRANSPARENT),
 
-  /* Special flag to tag unaligned BVH nodes.
-   * Only set and used in BVH nodes to distinguish how to interpret bounding box information stored
-   * in the node (either it should be intersected as AABB or as OBBU). */
-  PATH_RAY_NODE_UNALIGNED = (1U << 10U),
-
   /* Subset of flags used for ray visibility for intersection.
    *
    * NOTE: SHADOW_CATCHER macros below assume there are no more than
    * 16 visibility bits. */
-  PATH_RAY_ALL_VISIBILITY = ((1U << 11U) - 1U),
+  PATH_RAY_ALL_VISIBILITY = ((1U << 10U) - 1U),
+
+  /* Special flag to tag unaligned BVH nodes.
+   * Only set and used in BVH nodes to distinguish how to interpret bounding box information stored
+   * in the node (either it should be intersected as AABB or as OBBU).
+   * So this can overlap with path flags. */
+  PATH_RAY_NODE_UNALIGNED = (1U << 10U),
 
   /* --------------------------------------------------------------------
    * Path flags.
    */
 
+  /* Surface had transmission component at previous bounce. Used for light tree
+   * traversal and culling to be consistent with MIS pdf at the next bounce. */
+  PATH_RAY_MIS_HAD_TRANSMISSION = (1U << 10U),
+
   /* Don't apply multiple importance sampling weights to emission from
    * lamp or surface hits, because they were not direct light sampled. */
   PATH_RAY_MIS_SKIP = (1U << 11U),



More information about the Bf-blender-cvs mailing list