[Bf-blender-cvs] [be5c9872671] cycles-x: Cycles: Refactor shadow catcher ray visibility

Sergey Sharybin noreply at git.blender.org
Tue May 4 15:54:36 CEST 2021


Commit: be5c9872671ef12c9c1295a5481d6f0682350230
Author: Sergey Sharybin
Date:   Mon May 3 12:14:54 2021 +0200
Branches: cycles-x
https://developer.blender.org/rBbe5c9872671ef12c9c1295a5481d6f0682350230

Cycles: Refactor shadow catcher ray visibility

Allow to "filter" shadow catcher objects by any of the visibility
(diffuse, glossy, and so on) to allow complete separation of objects
in the scene.

Implemented as a bitmask shift magic: shadow catcher objects have their
visibility "duplicated" as a shift left by 16. The ray visibility for
tracing will use either low or high visibility bits depending on whether
shadow catcher object was hit or not.

Currently no functional changes, just committing separately to make it
easier to bisect possible unintended functional changes.

Initial idea implementation from Brecht, adopted to the shadow catcher
code by self.

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

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

M	intern/cycles/kernel/integrator/integrator_intersect_shadow.h
M	intern/cycles/kernel/kernel_path_state.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/render/object.cpp
M	intern/cycles/render/osl.cpp

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

diff --git a/intern/cycles/kernel/integrator/integrator_intersect_shadow.h b/intern/cycles/kernel/integrator/integrator_intersect_shadow.h
index 11aa5fe1e90..7572d96da47 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_shadow.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_shadow.h
@@ -18,14 +18,17 @@
 
 CCL_NAMESPACE_BEGIN
 
+/* Visibility for the shadow ray. */
 ccl_device_forceinline uint integrate_intersect_shadow_visibility(INTEGRATOR_STATE_CONST_ARGS)
 {
+  uint visibility = PATH_RAY_SHADOW;
+
+#ifdef __SHADOW_CATCHER__
   const uint32_t path_flag = INTEGRATOR_STATE(shadow_path, flag);
-#ifdef __SHADOW_TRICKS__
-  return (path_flag & PATH_RAY_SHADOW_CATCHER) ? PATH_RAY_SHADOW_NON_CATCHER : PATH_RAY_SHADOW;
-#else
-  return PATH_RAY_SHADOW;
+  visibility = SHADOW_CATCHER_PATH_VISIBILITY(path_flag, visibility);
 #endif
+
+  return visibility;
 }
 
 ccl_device bool integrate_intersect_shadow_opaque(INTEGRATOR_STATE_ARGS,
@@ -34,8 +37,15 @@ ccl_device bool integrate_intersect_shadow_opaque(INTEGRATOR_STATE_ARGS,
 {
   PROFILING_INIT(kg, PROFILING_SCENE_INTERSECT);
 
+  /* Mask which will pick only opaque visibility bits from the `visibility`.
+   * Calculate the mask at compile time: the visibility will either be a high bits for the shadow
+   * catcher objects, or lower bits for the regular objects (there is no need to check the path
+   * state here again). */
+  ccl_constexpr const uint opaque_mask = SHADOW_CATCHER_VISIBILITY_SHIFT(PATH_RAY_SHADOW_OPAQUE) |
+                                         PATH_RAY_SHADOW_OPAQUE;
+
   Intersection isect;
-  const bool opaque_hit = scene_intersect(kg, ray, visibility & PATH_RAY_SHADOW_OPAQUE, &isect);
+  const bool opaque_hit = scene_intersect(kg, ray, visibility & opaque_mask, &isect);
 
   if (!opaque_hit) {
     INTEGRATOR_STATE_WRITE(shadow_path, num_hits) = 0;
diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h
index 1f537db984b..d725b483a51 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -222,15 +222,21 @@ ccl_device_inline bool path_state_volume_next(INTEGRATOR_STATE_ARGS)
 
 ccl_device_inline uint path_state_ray_visibility(INTEGRATOR_STATE_CONST_ARGS)
 {
-  const uint32_t flag = INTEGRATOR_STATE(path, flag);
-  uint32_t visibility = flag & PATH_RAY_ALL_VISIBILITY;
+  const uint32_t path_flag = INTEGRATOR_STATE(path, flag);
+
+  uint32_t visibility = path_flag & PATH_RAY_ALL_VISIBILITY;
 
   /* For visibility, diffuse/glossy are for reflection only. */
-  if (visibility & PATH_RAY_TRANSMIT)
+  if (visibility & PATH_RAY_TRANSMIT) {
     visibility &= ~(PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY);
+  }
+
   /* todo: this is not supported as its own ray visibility yet. */
-  if (flag & PATH_RAY_VOLUME_SCATTER)
+  if (path_flag & PATH_RAY_VOLUME_SCATTER) {
     visibility |= PATH_RAY_DIFFUSE;
+  }
+
+  visibility = SHADOW_CATCHER_PATH_VISIBILITY(path_flag, visibility);
 
   return visibility;
 }
@@ -249,12 +255,6 @@ ccl_device_inline float path_state_continuation_probability(INTEGRATOR_STATE_CON
     if (transparent_bounce <= kernel_data.integrator.transparent_min_bounce) {
       return 1.0f;
     }
-#ifdef __SHADOW_TRICKS__
-    /* Exception for shadow catcher not working correctly with RR. */
-    else if ((flag & PATH_RAY_SHADOW_CATCHER) && (transparent_bounce <= 8)) {
-      return 1.0f;
-    }
-#endif
   }
   else {
     const uint32_t bounce = INTEGRATOR_STATE(path, bounce);
@@ -262,12 +262,6 @@ ccl_device_inline float path_state_continuation_probability(INTEGRATOR_STATE_CON
     if (bounce <= kernel_data.integrator.min_bounce) {
       return 1.0f;
     }
-#ifdef __SHADOW_TRICKS__
-    /* Exception for shadow catcher not working correctly with RR. */
-    else if ((flag & PATH_RAY_SHADOW_CATCHER) && (bounce <= 3)) {
-      return 1.0f;
-    }
-#endif
   }
 
   /* Probabilistic termination: use sqrt() to roughly match typical view
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 09b14cea2dc..349d0064836 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -253,7 +253,12 @@ enum SamplingPattern {
 /* these flags values correspond to raytypes in osl.cpp, so keep them in sync! */
 
 enum PathRayFlag {
-  /* Ray visibility. */
+  /* --------------------------------------------------------------------
+   * Ray visibility.
+   *
+   * NOTE: Recalculated after a surface bounce.
+   */
+
   PATH_RAY_CAMERA = (1 << 0),
   PATH_RAY_REFLECT = (1 << 1),
   PATH_RAY_TRANSMIT = (1 << 2),
@@ -261,68 +266,98 @@ enum PathRayFlag {
   PATH_RAY_GLOSSY = (1 << 4),
   PATH_RAY_SINGULAR = (1 << 5),
   PATH_RAY_TRANSPARENT = (1 << 6),
+  PATH_RAY_VOLUME_SCATTER = (1 << 7),
 
   /* Shadow ray visibility. */
-  PATH_RAY_SHADOW_OPAQUE_NON_CATCHER = (1 << 7),
-  PATH_RAY_SHADOW_OPAQUE_CATCHER = (1 << 8),
-  PATH_RAY_SHADOW_OPAQUE = (PATH_RAY_SHADOW_OPAQUE_NON_CATCHER | PATH_RAY_SHADOW_OPAQUE_CATCHER),
-  PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER = (1 << 9),
-  PATH_RAY_SHADOW_TRANSPARENT_CATCHER = (1 << 10),
-  PATH_RAY_SHADOW_TRANSPARENT = (PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER |
-                                 PATH_RAY_SHADOW_TRANSPARENT_CATCHER),
-  PATH_RAY_SHADOW_NON_CATCHER = (PATH_RAY_SHADOW_OPAQUE_NON_CATCHER |
-                                 PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER),
+  PATH_RAY_SHADOW_OPAQUE = (1 << 8),
+  PATH_RAY_SHADOW_TRANSPARENT = (1 << 9),
   PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE | PATH_RAY_SHADOW_TRANSPARENT),
 
-  /* Unused, free to reuse. */
-  PATH_RAY_UNUSED = (1 << 11),
-
-  /* Ray visibility for volume scattering. */
-  PATH_RAY_VOLUME_SCATTER = (1 << 12),
+  /* 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 OBB). */
+  PATH_RAY_NODE_UNALIGNED = (1 << 10),
 
-  /* Special flag to tag unaligned BVH nodes. */
-  PATH_RAY_NODE_UNALIGNED = (1 << 13),
+  /* 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 = ((1 << 11) - 1),
 
-  PATH_RAY_ALL_VISIBILITY = ((1 << 14) - 1),
+  /* --------------------------------------------------------------------
+   * Path flags.
+   */
 
   /* 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 = (1 << 14),
+  PATH_RAY_MIS_SKIP = (1 << 11),
+
   /* Diffuse bounce earlier in the path, skip SSS to improve performance
    * and avoid branching twice with disk sampling SSS. */
-  PATH_RAY_DIFFUSE_ANCESTOR = (1 << 15),
+  PATH_RAY_DIFFUSE_ANCESTOR = (1 << 12),
+
   /* Single pass has been written. */
-  PATH_RAY_SINGLE_PASS_DONE = (1 << 16),
-  /* Ray is behind a shadow catcher .*/
-  PATH_RAY_SHADOW_CATCHER = (1 << 17),
-  /* Store shadow data for shadow catcher or denoising. */
-  PATH_RAY_STORE_SHADOW_INFO = (1 << 18),
+  PATH_RAY_SINGLE_PASS_DONE = (1 << 13),
+
   /* Zero background alpha, for camera or transparent glass rays. */
-  PATH_RAY_TRANSPARENT_BACKGROUND = (1 << 19),
+  PATH_RAY_TRANSPARENT_BACKGROUND = (1 << 14),
+
   /* Terminate ray immediately at next bounce. */
-  PATH_RAY_TERMINATE_IMMEDIATE = (1 << 20),
+  PATH_RAY_TERMINATE_IMMEDIATE = (1 << 15),
+
   /* Ray is to be terminated, but continue with transparent bounces and
    * emission as long as we encounter them. This is required to make the
    * MIS between direct and indirect light rays match, as shadow rays go
    * through transparent surfaces to reach emission too. */
-  PATH_RAY_TERMINATE_AFTER_TRANSPARENT = (1 << 21),
+  PATH_RAY_TERMINATE_AFTER_TRANSPARENT = (1 << 16),
+
   /* Ray is to be terminated. */
   PATH_RAY_TERMINATE = (PATH_RAY_TERMINATE_IMMEDIATE | PATH_RAY_TERMINATE_AFTER_TRANSPARENT),
+
   /* Path and shader is being evaluated for direct lighting emission. */
-  PATH_RAY_EMISSION = (1 << 22),
+  PATH_RAY_EMISSION = (1 << 17),
+
   /* Perform subsurface scattering. */
-  PATH_RAY_SUBSURFACE = (1 << 23),
+  PATH_RAY_SUBSURFACE = (1 << 18),
+
   /* Contribute to denoising features. */
-  PATH_RAY_DENOISING_FEATURES = (1 << 24),
+  PATH_RAY_DENOISING_FEATURES = (1 << 19),
+
   /* Render pass categories. */
-  PATH_RAY_REFLECT_PASS = (1 << 25),
-  PATH_RAY_TRANSMISSION_PASS = (1 << 26),
-  PATH_RAY_VOLUME_PASS = (1 << 27),
+  PATH_RAY_REFLECT_PASS = (1 << 20),
+  PATH_RAY_TRANSMISSION_PASS = (1 << 21),
+  PATH_RAY_VOLUME_PASS = (1 << 22),
   PATH_RAY_ANY_PASS = (PATH_RAY_REFLECT_PASS | PATH_RAY_TRANSMISSION_PASS | PATH_RAY_VOLUME_PASS),
+
   /* Shadow ray is for a light or surface. */
-  PATH_RAY_SHADOW_FOR_LIGHT = (1 << 28),
+  PATH_RAY_SHADOW_FOR_LIGHT = (1 << 23),
+
+  /* A shadow catcher object was hit and the path was split into two. */
+  PATH_RAY_SHADOW_CATCHER_HIT = (1 << 24),
+
+  /* A shadow catcher object was hit and this path traces only shadow catchers, writing them into
+   * their dedicated pass for later division.
+   *
+   * NOTE: Is not covered with `PATH_RAY_ANY_PASS` because shadow catcher does special handling
+   * which is separate from the light passes. */
+  PATH_RAY_SHADOW_CATCHER_PASS = (1 << 25),
 };
 
+/* Configure ray visibility bits for rays and objects respectively,
+ * to make shadow catchers work.
+ *
+ * On shadow catcher paths we want to ignore any intersections with non-catchers,
+ * whereas on regular paths we want to intersect all objects. */
+
+#define SHADOW_CATCHER_VISIBILITY_SHIFT(visibility) ((visibility) << 16)
+
+#define SHADOW_CATCHER_PATH_VISIBILITY(path_flag, visibility) \
+  (((path_flag)&PATH_RAY_SHADOW_CATCHER_PASS) ? SHADOW_CATCHER_VISIBILITY_SHIFT(visibility) : \
+                                                (visibility))
+
+#define SHADOW_CATCHER_OBJECT_VISIBILITY(is_shadow_catcher, visibility) \
+  (((is_shadow_catcher) ? SHADOW_CATCHER_VISIBILITY_SHIFT(visibility) : 0) | (visibility))
+
 /* Closure Label */
 
 typedef enum ClosureLabel {
diff --git a/intern/cycles/render/object.cpp b/inter

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list