[Bf-blender-cvs] [14a3ceae0a4] cycles-x: Cycles X: restore support for rendering SSS inside volumes

Brecht Van Lommel noreply at git.blender.org
Fri Jul 23 20:19:34 CEST 2021


Commit: 14a3ceae0a47bb3ec8dc71432db3818775a284d5
Author: Brecht Van Lommel
Date:   Fri Jul 23 19:34:26 2021 +0200
Branches: cycles-x
https://developer.blender.org/rB14a3ceae0a47bb3ec8dc71432db3818775a284d5

Cycles X: restore support for rendering SSS inside volumes

I found no GPU rendering performance difference in the two benchmark scenes
with SSS: junkshop and monster. In scenes with overlap between SSS and volumes
there will of course be a slowdown.

There is test reports/T39823 for this, which now seems to work correctly.

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

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

M	intern/cycles/kernel/integrator/integrator_intersect_subsurface.h
M	intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h
M	intern/cycles/kernel/integrator/integrator_subsurface.h

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

diff --git a/intern/cycles/kernel/integrator/integrator_intersect_subsurface.h b/intern/cycles/kernel/integrator/integrator_intersect_subsurface.h
index b8bafd8d1bc..93831c67cf4 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_subsurface.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_subsurface.h
@@ -28,25 +28,6 @@ ccl_device void integrator_intersect_subsurface(INTEGRATOR_STATE_ARGS)
   }
 #endif
 
-  /* TODO: update volume stack. Instead of a special for_subsurface, we could
-   * just re-init the volume stack completely, sharing the same kernel as for
-   * cameras. */
-#if 0
-#  ifdef __VOLUME__
-  bool need_update_volume_stack = kernel_data.integrator.use_volumes &&
-                                  sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
-
-  if (need_update_volume_stack) {
-    Ray volume_ray = *ray;
-    /* Setup ray from previous surface point to the new one. */
-    volume_ray.D = normalize_len(hit_ray->P - volume_ray.P, &volume_ray.t);
-
-    kernel_volume_stack_update_for_subsurface(
-        kg, emission_sd, &volume_ray, hit_state->volume_stack);
-  }
-#  endif /* __VOLUME__ */
-#endif
-
   INTEGRATOR_PATH_TERMINATE(DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE);
 }
 
diff --git a/intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h b/intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h
index daec67dc358..b7cd3f27531 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_volume_stack.h
@@ -23,6 +23,51 @@
 
 CCL_NAMESPACE_BEGIN
 
+ccl_device void integrator_volume_stack_update_for_subsurface(INTEGRATOR_STATE_ARGS,
+                                                              const float3 from_P,
+                                                              const float3 to_P)
+{
+  ShaderDataTinyStorage stack_sd_storage;
+  ShaderData *stack_sd = AS_SHADER_DATA(&stack_sd_storage);
+
+  kernel_assert(kernel_data.integrator.use_volumes);
+
+  Ray volume_ray ccl_optional_struct_init;
+  volume_ray.P = from_P;
+  volume_ray.D = normalize_len(to_P - from_P, &volume_ray.t);
+
+#ifdef __VOLUME_RECORD_ALL__
+  Intersection hits[2 * VOLUME_STACK_SIZE + 1];
+  uint num_hits = scene_intersect_volume_all(
+      kg, &volume_ray, hits, 2 * VOLUME_STACK_SIZE, PATH_RAY_ALL_VISIBILITY);
+  if (num_hits > 0) {
+    Intersection *isect = hits;
+
+    qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
+
+    for (uint hit = 0; hit < num_hits; ++hit, ++isect) {
+      shader_setup_from_ray(kg, stack_sd, &volume_ray, isect);
+      volume_stack_enter_exit(INTEGRATOR_STATE_PASS, stack_sd);
+    }
+  }
+#else
+  Intersection isect;
+  int step = 0;
+  while (step < 2 * VOLUME_STACK_SIZE &&
+         scene_intersect_volume(kg, &volume_ray, &isect, PATH_RAY_ALL_VISIBILITY)) {
+    shader_setup_from_ray(kg, stack_sd, &volume_ray, &isect);
+    volume_stack_enter_exit(INTEGRATOR_STATE_PASS, stack_sd);
+
+    /* Move ray forward. */
+    volume_ray.P = ray_offset(stack_sd->P, -stack_sd->Ng);
+    if (volume_ray.t != FLT_MAX) {
+      volume_ray.D = normalize_len(to_P - volume_ray.P, &volume_ray.t);
+    }
+    ++step;
+  }
+#endif
+}
+
 ccl_device void integrator_intersect_volume_stack(INTEGRATOR_STATE_ARGS)
 {
   ShaderDataTinyStorage stack_sd_storage;
diff --git a/intern/cycles/kernel/integrator/integrator_subsurface.h b/intern/cycles/kernel/integrator/integrator_subsurface.h
index 5522b6b4028..8c438223b66 100644
--- a/intern/cycles/kernel/integrator/integrator_subsurface.h
+++ b/intern/cycles/kernel/integrator/integrator_subsurface.h
@@ -28,6 +28,8 @@
 #include "kernel/closure/bssrdf.h"
 #include "kernel/closure/volume.h"
 
+#include "kernel/integrator/integrator_intersect_volume_stack.h"
+
 CCL_NAMESPACE_BEGIN
 
 #ifdef __SUBSURFACE__
@@ -301,9 +303,11 @@ ccl_device_inline bool subsurface_random_walk(INTEGRATOR_STATE_ARGS)
   Transform ob_tfm = object_fetch_transform_motion_test(kg, object, time, &ob_itfm);
 #  endif
 
+  const float3 ray_start_P = ray_offset(P, -Ng);
+
   /* Setup ray. */
   Ray ray ccl_optional_struct_init;
-  ray.P = ray_offset(P, -Ng);
+  ray.P = ray_start_P;
   ray.D = D;
   ray.t = FLT_MAX;
   ray.time = time;
@@ -525,6 +529,18 @@ ccl_device_inline bool subsurface_random_walk(INTEGRATOR_STATE_ARGS)
     return false;
   }
 
+#  ifdef __VOLUME__
+  /* Update volume stack if needed. */
+  if (kernel_data.integrator.use_volumes) {
+    const int object = intersection_get_object(kg, &ss_isect.hits[0]);
+    const int object_flag = kernel_tex_fetch(__object_flag, object);
+
+    if (object_flag & SD_OBJECT_INTERSECTS_VOLUME) {
+      integrator_volume_stack_update_for_subsurface(INTEGRATOR_STATE_PASS, ray_start_P, ray.P);
+    }
+  }
+#  endif /* __VOLUME__ */
+
   /* Pretend ray is coming from the outside towards the exit point. This ensures
    * correct front/back facing normals.
    * TODO: find a more elegant solution? */



More information about the Bf-blender-cvs mailing list