[Bf-blender-cvs] [ef4f3201b73] cycles-x: Fix various issues in shadow handling of volumes

Brecht Van Lommel noreply at git.blender.org
Mon Jun 28 17:15:23 CEST 2021


Commit: ef4f3201b731cc48ae330e84f91597ab0345196c
Author: Brecht Van Lommel
Date:   Thu Jun 17 17:22:41 2021 +0200
Branches: cycles-x
https://developer.blender.org/rBef4f3201b731cc48ae330e84f91597ab0345196c

Fix various issues in shadow handling of volumes

Properly compute volume shading for all segments before, between and after
surface hits.

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

M	intern/cycles/kernel/integrator/integrator_intersect_shadow.h
M	intern/cycles/kernel/integrator/integrator_shade_shadow.h
M	intern/cycles/kernel/integrator/integrator_shade_surface.h
M	intern/cycles/kernel/integrator/integrator_state_util.h
M	intern/cycles/kernel/integrator/integrator_subsurface.h

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

diff --git a/intern/cycles/kernel/integrator/integrator_intersect_shadow.h b/intern/cycles/kernel/integrator/integrator_intersect_shadow.h
index 06830d3d1c9..0582670a5da 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_shadow.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_shadow.h
@@ -97,6 +97,9 @@ ccl_device bool integrate_intersect_shadow_transparent(INTEGRATOR_STATE_ARGS,
 
     INTEGRATOR_STATE_WRITE(shadow_path, num_hits) = num_hits;
   }
+  else {
+    INTEGRATOR_STATE_WRITE(shadow_path, num_hits) = 0;
+  }
 
   return opaque_hit;
 }
diff --git a/intern/cycles/kernel/integrator/integrator_shade_shadow.h b/intern/cycles/kernel/integrator/integrator_shade_shadow.h
index 975ad750df8..d140a7461d4 100644
--- a/intern/cycles/kernel/integrator/integrator_shade_shadow.h
+++ b/intern/cycles/kernel/integrator/integrator_shade_shadow.h
@@ -59,7 +59,9 @@ ccl_device_inline float3 integrate_transparent_surface_shadow(INTEGRATOR_STATE_A
 }
 
 #  ifdef __VOLUME__
-ccl_device_inline float3 integrate_transparent_volume_shadow(INTEGRATOR_STATE_ARGS, const int hit)
+ccl_device_inline float3 integrate_transparent_volume_shadow(INTEGRATOR_STATE_ARGS,
+                                                             const int hit,
+                                                             const int num_recorded_hits)
 {
   /* TODO: deduplicate with surface, or does it not matter for memory usage? */
   ShaderDataTinyStorage shadow_sd_storage;
@@ -67,10 +69,14 @@ ccl_device_inline float3 integrate_transparent_volume_shadow(INTEGRATOR_STATE_AR
 
   /* Setup shader data. */
   Ray ray ccl_optional_struct_init;
-  integrator_state_read_ray(INTEGRATOR_STATE_PASS, &ray);
+  integrator_state_read_shadow_ray(INTEGRATOR_STATE_PASS, &ray);
 
-  Intersection isect ccl_optional_struct_init;
-  integrator_state_read_shadow_isect(INTEGRATOR_STATE_PASS, &isect, hit);
+  /* Modify ray position and length to match current segment. */
+  const float start_t = (hit == 0) ? 0.0f : INTEGRATOR_STATE_ARRAY(shadow_isect, hit - 1, t);
+  const float end_t = (hit < num_recorded_hits) ? INTEGRATOR_STATE_ARRAY(shadow_isect, hit, t) :
+                                                  ray.t;
+  ray.P += start_t * ray.D;
+  ray.t = end_t - start_t;
 
   shader_setup_from_volume(kg, shadow_sd, &ray);
 
@@ -81,49 +87,55 @@ ccl_device_inline float3 integrate_transparent_volume_shadow(INTEGRATOR_STATE_AR
   }
 
   /* Integrate extinction over segment. */
-  const float start_t = (hit == 0) ? 0.0f : INTEGRATOR_STATE_ARRAY(shadow_isect, hit - 1, t);
-  const float end_t = isect.t;
-  const float t = end_t - start_t;
-
-  return exp3(-sigma_a * t);
+  return volume_color_transmittance(sigma_a, ray.t);
 }
 #  endif
 
+ccl_device_inline bool shadow_intersections_has_remaining(const int num_hits)
+{
+  return num_hits >= INTEGRATOR_SHADOW_ISECT_SIZE;
+}
+
 ccl_device_inline bool integrate_transparent_shadow(INTEGRATOR_STATE_ARGS, const int num_hits)
 {
   /* Accumulate shadow for transparent surfaces. */
   const int num_recorded_hits = min(num_hits, INTEGRATOR_SHADOW_ISECT_SIZE);
 
-  for (int hit = 0; hit < num_recorded_hits; hit++) {
-#  ifdef __VOLUME__
+  for (int hit = 0; hit < num_recorded_hits + 1; hit++) {
     /* Volume shaders. */
-    if (INTEGRATOR_STATE_ARRAY(shadow_volume_stack, 0, shader) != SHADER_NONE) {
-      const float3 shadow = integrate_transparent_volume_shadow(INTEGRATOR_STATE_PASS, hit);
+    if (hit < num_recorded_hits || !shadow_intersections_has_remaining(num_hits)) {
+#  ifdef __VOLUME__
+      if (INTEGRATOR_STATE_ARRAY(shadow_volume_stack, 0, shader) != SHADER_NONE) {
+        const float3 shadow = integrate_transparent_volume_shadow(
+            INTEGRATOR_STATE_PASS, hit, num_recorded_hits);
+        const float3 throughput = INTEGRATOR_STATE(shadow_path, throughput) * shadow;
+        if (is_zero(throughput)) {
+          return true;
+        }
+
+        INTEGRATOR_STATE_WRITE(shadow_path, throughput) = throughput;
+      }
+#  endif
+    }
+
+    /* Surface shaders. */
+    if (hit < num_recorded_hits) {
+      const float3 shadow = integrate_transparent_surface_shadow(INTEGRATOR_STATE_PASS, hit);
       const float3 throughput = INTEGRATOR_STATE(shadow_path, throughput) * shadow;
       if (is_zero(throughput)) {
         return true;
       }
 
       INTEGRATOR_STATE_WRITE(shadow_path, throughput) = throughput;
+      INTEGRATOR_STATE_WRITE(shadow_path, transparent_bounce) += 1;
     }
-#  endif
-
-    /* Surface shaders. */
-    const float3 shadow = integrate_transparent_surface_shadow(INTEGRATOR_STATE_PASS, hit);
-    const float3 throughput = INTEGRATOR_STATE(shadow_path, throughput) * shadow;
-    if (is_zero(throughput)) {
-      return true;
-    }
-
-    INTEGRATOR_STATE_WRITE(shadow_path, throughput) = throughput;
-    INTEGRATOR_STATE_WRITE(shadow_path, transparent_bounce) += 1;
 
     /* Note we do not need to check max_transparent_bounce here, the number
      * of intersections is already limited and made opaque in the
      * INTERSECT_SHADOW kernel. */
   }
 
-  if (num_hits >= INTEGRATOR_SHADOW_ISECT_SIZE) {
+  if (shadow_intersections_has_remaining(num_hits)) {
     /* There are more hits that we could not recorded due to memory usage,
      * adjust ray to intersect again from the last hit. */
     const float last_hit_t = INTEGRATOR_STATE_ARRAY(shadow_isect, num_recorded_hits - 1, t);
@@ -151,7 +163,7 @@ ccl_device void integrator_shade_shadow(INTEGRATOR_STATE_ARGS,
   }
 #endif
 
-  if (num_hits >= INTEGRATOR_SHADOW_ISECT_SIZE) {
+  if (shadow_intersections_has_remaining(num_hits)) {
     /* More intersections to find, continue shadow ray. */
     INTEGRATOR_SHADOW_PATH_NEXT(DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW,
                                 DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW);
diff --git a/intern/cycles/kernel/integrator/integrator_shade_surface.h b/intern/cycles/kernel/integrator/integrator_shade_surface.h
index d305f20d361..f06813a7178 100644
--- a/intern/cycles/kernel/integrator/integrator_shade_surface.h
+++ b/intern/cycles/kernel/integrator/integrator_shade_surface.h
@@ -178,7 +178,7 @@ ccl_device_forceinline void integrate_surface_direct_light(INTEGRATOR_STATE_ARGS
 
   integrator_state_copy_volume_stack_to_shadow(INTEGRATOR_STATE_PASS);
 
-  /* Branch of shadow kernel. */
+  /* Branch off shadow kernel. */
   INTEGRATOR_SHADOW_PATH_INIT(DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW);
 }
 #endif
diff --git a/intern/cycles/kernel/integrator/integrator_state_util.h b/intern/cycles/kernel/integrator/integrator_state_util.h
index ec811088b2c..2d38522e9b7 100644
--- a/intern/cycles/kernel/integrator/integrator_state_util.h
+++ b/intern/cycles/kernel/integrator/integrator_state_util.h
@@ -157,8 +157,8 @@ ccl_device_forceinline void integrator_state_copy_volume_stack_to_shadow(INTEGRA
 ccl_device_forceinline VolumeStack
 integrator_state_read_shadow_volume_stack(INTEGRATOR_STATE_CONST_ARGS, int i)
 {
-  VolumeStack entry = {INTEGRATOR_STATE_ARRAY(volume_stack, i, object),
-                       INTEGRATOR_STATE_ARRAY(volume_stack, i, shader)};
+  VolumeStack entry = {INTEGRATOR_STATE_ARRAY(shadow_volume_stack, i, object),
+                       INTEGRATOR_STATE_ARRAY(shadow_volume_stack, i, shader)};
   return entry;
 }
 
diff --git a/intern/cycles/kernel/integrator/integrator_subsurface.h b/intern/cycles/kernel/integrator/integrator_subsurface.h
index a25e84519d5..fe7bb1f3000 100644
--- a/intern/cycles/kernel/integrator/integrator_subsurface.h
+++ b/intern/cycles/kernel/integrator/integrator_subsurface.h
@@ -124,7 +124,7 @@ ccl_device bool subsurface_bounce(INTEGRATOR_STATE_ARGS, ShaderData *sd, const S
   INTEGRATOR_STATE_WRITE(subsurface, radius) = bssrdf->radius;
   INTEGRATOR_STATE_WRITE(subsurface, roughness) = roughness;
 
-  return true;
+  return LABEL_SUBSURFACE_SCATTER;
 }
 
 ccl_device void subsurface_shader_data_setup(INTEGRATOR_STATE_ARGS, ShaderData *sd)



More information about the Bf-blender-cvs mailing list