Commit: aa46459543e7ff26ad5d2ba7801ad0a0a0bc99fc
Author: Sergey Sharybin
Date:   Wed Oct 13 15:55:54 2021 +0200
Branches: master
https://developer.blender.org/rBaa46459543e7ff26ad5d2ba7801ad0a0a0bc99fc

Fix shadow catcher behind transparent object on GPU

The assumption about absent shadow path was wrong.

The rest of the changes are to ensure shadow paths are finished prior
to the split, so that they write to the proper passes.

The issue was caught by running regression tests on OptiX.

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

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

M       intern/cycles/integrator/path_trace_work_gpu.cpp
M       intern/cycles/kernel/integrator/integrator_intersect_closest.h
M       intern/cycles/kernel/integrator/integrator_state_util.h

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

diff --git a/intern/cycles/integrator/path_trace_work_gpu.cpp 
b/intern/cycles/integrator/path_trace_work_gpu.cpp
index df393bac0de..02830a00405 100644
--- a/intern/cycles/integrator/path_trace_work_gpu.cpp
+++ b/intern/cycles/integrator/path_trace_work_gpu.cpp
@@ -342,10 +342,14 @@ bool PathTraceWorkGPU::enqueue_path_iteration()
   }
 
   /* Finish shadows before potentially adding more shadow rays. We can only
-   * store one shadow ray in the integrator state. */
+   * store one shadow ray in the integrator state.
+   *
+   * When there is a shadow catcher in the scene finish shadow rays before 
invoking interesect
+   * closest kernel since so that the shadow paths are writing to the 
pre-split state. */
   if (kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE ||
       kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE ||
-      kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME) {
+      kernel == DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME ||
+      (has_shadow_catcher() && kernel == 
DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST)) {
     if (queue_counter->num_queued[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW]) {
       enqueue_path_iteration(DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW);
       return true;
diff --git a/intern/cycles/kernel/integrator/integrator_intersect_closest.h 
b/intern/cycles/kernel/integrator/integrator_intersect_closest.h
index 579a9c4d200..cd9af1c62fc 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_closest.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_closest.h
@@ -126,12 +126,7 @@ ccl_device_forceinline void 
integrator_intersect_shader_next_kernel(
     if (kernel_data.film.pass_background != PASS_UNUSED && 
!kernel_data.background.transparent) {
       INTEGRATOR_STATE_WRITE(path, flag) |= PATH_RAY_SHADOW_CATCHER_BACKGROUND;
 
-      if (use_raytrace_kernel) {
-        INTEGRATOR_PATH_INIT(DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
-      }
-      else {
-        INTEGRATOR_PATH_INIT(DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
-      }
+      INTEGRATOR_PATH_INIT(DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
     }
     else if (use_raytrace_kernel) {
       
INTEGRATOR_PATH_INIT_SORTED(DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE, 
shader);
@@ -139,6 +134,13 @@ ccl_device_forceinline void 
integrator_intersect_shader_next_kernel(
     else {
       INTEGRATOR_PATH_INIT_SORTED(DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE, 
shader);
     }
+
+    /* If the split happened after bounce through a transparent object it's 
possible to have shadow
+     * patch. Make sure it is properly re-scheduled on the split path. */
+    const int shadow_kernel = INTEGRATOR_STATE(shadow_path, queued_kernel);
+    if (shadow_kernel != 0) {
+      INTEGRATOR_SHADOW_PATH_INIT(shadow_kernel);
+    }
   }
 #endif
 }
diff --git a/intern/cycles/kernel/integrator/integrator_state_util.h 
b/intern/cycles/kernel/integrator/integrator_state_util.h
index 01d596b690a..037c7533943 100644
--- a/intern/cycles/kernel/integrator/integrator_state_util.h
+++ b/intern/cycles/kernel/integrator/integrator_state_util.h
@@ -262,12 +262,6 @@ ccl_device_inline void 
integrator_state_shadow_catcher_split(INTEGRATOR_STATE_AR
   integrator_state_copy_only(to_state, state);
 
   kernel_integrator_state.path.flag[to_state] |= PATH_RAY_SHADOW_CATCHER_PASS;
-
-  /* Sanity check: expect to split in the intersect-closest kernel, where 
there is no shadow ray
-   * and no sorting yet. */
-  kernel_assert(INTEGRATOR_STATE(shadow_path, queued_kernel) == 0);
-  
kernel_assert(kernel_integrator_state.sort_key_counter[INTEGRATOR_STATE(path, 
queued_kernel)] ==
-                nullptr);
 #else
 
   IntegratorStateCPU *ccl_restrict split_state = state + 1;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to