[Bf-blender-cvs] [04e89c5b067] master: Fix T96165: Incorrect render of barcelone scene with BVH2 Fix T95462: Partly transparent objects appear to glow in the dark

Sergey Sharybin noreply at git.blender.org
Wed Mar 9 10:38:48 CET 2022


Commit: 04e89c5b06739a9a507942e2a9c67fb59b975600
Author: Sergey Sharybin
Date:   Tue Mar 8 14:43:48 2022 +0100
Branches: master
https://developer.blender.org/rB04e89c5b06739a9a507942e2a9c67fb59b975600

Fix T96165: Incorrect render of barcelone scene with BVH2
Fix T95462: Partly transparent objects appear to glow in the dark

The issue was caused by incorrect check for exceeded number
of transparent bounces: the same maximum distance was used
for picking up N closest intersections and counting overall
intersections count.

Now made it so intersection count is using ray distance which
matches the way how Embree and OptiX implementation works.

Benchmark result:
{F12907888}

There is no big time difference in the pabellon scene. The
Victor scene timing doesn't seem to be very reliable as the
variance in time across different benchmark runs is quite
high.

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

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

M	intern/cycles/kernel/bvh/shadow_all.h

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

diff --git a/intern/cycles/kernel/bvh/shadow_all.h b/intern/cycles/kernel/bvh/shadow_all.h
index a5769e91a28..2f58929c1e5 100644
--- a/intern/cycles/kernel/bvh/shadow_all.h
+++ b/intern/cycles/kernel/bvh/shadow_all.h
@@ -29,8 +29,8 @@ ccl_device_inline
                                      IntegratorShadowState state,
                                      const uint visibility,
                                      const uint max_hits,
-                                     ccl_private uint *num_recorded_hits,
-                                     ccl_private float *throughput)
+                                     ccl_private uint *r_num_recorded_hits,
+                                     ccl_private float *r_throughput)
 {
   /* todo:
    * - likely and unlikely for if() statements
@@ -60,15 +60,18 @@ ccl_device_inline
    * recorded hits is exceeded and we no longer need to find hits beyond the max
    * distance found. */
   float t_max_world = ray->t;
-  /* Equal to t_max_world when traversing top level BVH, transformed into local
-   * space when entering instances. */
-  float t_max_current = t_max_world;
+
+  /* Current maximum distance to the intersection.
+   * Is calculated as a ray length, transformed to an object space when entering
+   * instance node. */
+  float t_max_current = ray->t;
+
   /* Conversion from world to local space for the current instance if any, 1.0
    * otherwise. */
   float t_world_to_instance = 1.0f;
 
-  *num_recorded_hits = 0;
-  *throughput = 1.0f;
+  *r_num_recorded_hits = 0;
+  *r_throughput = 1.0f;
 
   /* traversal loop */
   do {
@@ -237,10 +240,10 @@ ccl_device_inline
 
               /* Always use baked shadow transparency for curves. */
               if (isect.type & PRIMITIVE_CURVE) {
-                *throughput *= intersection_curve_shadow_transparency(
+                *r_throughput *= intersection_curve_shadow_transparency(
                     kg, isect.object, isect.prim, isect.u);
 
-                if (*throughput < CURVE_SHADOW_TRANSPARENCY_CUTOFF) {
+                if (*r_throughput < CURVE_SHADOW_TRANSPARENCY_CUTOFF) {
                   return true;
                 }
                 else {
@@ -249,37 +252,39 @@ ccl_device_inline
               }
 
               if (record_intersection) {
-                /* Increase the number of hits, possibly beyond max_hits, we will
-                 * simply not record those and only keep the max_hits closest. */
-                uint record_index = (*num_recorded_hits)++;
-
+                /* Test if we need to record this transparent intersection. */
                 const uint max_record_hits = min(max_hits, INTEGRATOR_SHADOW_ISECT_SIZE);
-                if (record_index >= max_record_hits - 1) {
-                  /* If maximum number of hits reached, find the intersection with
-                   * the largest distance to potentially replace when another hit
-                   * is found. */
-                  const int num_recorded_hits = min(max_record_hits, record_index);
-                  float max_recorded_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, t);
-                  int max_recorded_hit = 0;
-
-                  for (int i = 1; i < num_recorded_hits; i++) {
-                    const float isect_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, i, t);
-                    if (isect_t > max_recorded_t) {
-                      max_recorded_t = isect_t;
-                      max_recorded_hit = i;
+                if (*r_num_recorded_hits < max_record_hits || isect.t < t_max_world) {
+                  /* If maximum number of hits was reached, replace the intersection with the
+                   * highest distance. We want to find the N closest intersections. */
+                  const uint num_recorded_hits = min(*r_num_recorded_hits, max_record_hits);
+                  uint isect_index = num_recorded_hits;
+                  if (num_recorded_hits + 1 >= max_record_hits) {
+                    float max_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, t);
+                    uint max_recorded_hit = 0;
+
+                    for (uint i = 1; i < num_recorded_hits; ++i) {
+                      const float isect_t = INTEGRATOR_STATE_ARRAY(state, shadow_isect, i, t);
+                      if (isect_t > max_t) {
+                        max_recorded_hit = i;
+                        max_t = isect_t;
+                      }
+                    }
+
+                    if (num_recorded_hits >= max_record_hits) {
+                      isect_index = max_recorded_hit;
                     }
-                  }
 
-                  if (record_index >= max_record_hits) {
-                    record_index = max_recorded_hit;
+                    /* Limit the ray distance and stop counting hits beyond this. */
+                    t_max_world = max(isect.t, max_t);
                   }
 
-                  /* Limit the ray distance and stop counting hits beyond this. */
-                  t_max_world = max(max_recorded_t, isect.t);
-                  t_max_current = t_max_world * t_world_to_instance;
+                  integrator_state_write_shadow_isect(state, &isect, isect_index);
                 }
 
-                integrator_state_write_shadow_isect(state, &isect, record_index);
+                /* Always increase the number of recorded hits, even beyond the maximum,
+                 * so that we can detect this and trace another ray if needed. */
+                ++(*r_num_recorded_hits);
               }
             }
           }
@@ -318,7 +323,7 @@ ccl_device_inline
 #endif
 
       /* Restore world space ray length. */
-      t_max_current = t_max_world;
+      t_max_current = ray->t;
 
       object = OBJECT_NONE;
       t_world_to_instance = 1.0f;



More information about the Bf-blender-cvs mailing list