[Bf-blender-cvs] [789b84e9d68] cycles-x: Fix possible NaN throughput in Cycles random walk

Sergey Sharybin noreply at git.blender.org
Tue May 18 10:53:05 CEST 2021


Commit: 789b84e9d686be003b37458801bec3dd10f962f3
Author: Sergey Sharybin
Date:   Wed May 12 12:47:26 2021 +0200
Branches: cycles-x
https://developer.blender.org/rB789b84e9d686be003b37458801bec3dd10f962f3

Fix possible NaN throughput in Cycles random walk

Based on asymptotic values of formulas when diffuse length is reaching
1 the throughput will be going to 0. So terminate the path early on
without causing numerical issues.

Just something I've notices with the Junk Shop scene while running
debugger for something else.

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

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

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

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

diff --git a/intern/cycles/kernel/integrator/integrator_subsurface.h b/intern/cycles/kernel/integrator/integrator_subsurface.h
index a5295ee2f72..a266eb45f5b 100644
--- a/intern/cycles/kernel/integrator/integrator_subsurface.h
+++ b/intern/cycles/kernel/integrator/integrator_subsurface.h
@@ -328,9 +328,17 @@ ccl_device_inline bool subsurface_random_walk(INTEGRATOR_STATE_ARGS)
    * Since the strength of the guided sampling increases as alpha gets lower, using a value that
    * is too low results in fireflies while one that's too high just gives a bit more noise.
    * Therefore, the code here uses the highest of the three albedos to be safe. */
-  float diffusion_length = diffusion_length_dwivedi(max3(alpha));
+  const float diffusion_length = diffusion_length_dwivedi(max3(alpha));
+
+  if (diffusion_length == 1.0f) {
+    /* With specific values of alpha the length might become 1, which in asymptotic makes phase to
+     * be infinite. After first bounce it will cause throughput to be 0. Do early output, avoiding
+     * numerical issues and extra unneeded work. */
+    return false;
+  }
+
   /* Precompute term for phase sampling. */
-  float phase_log = logf((diffusion_length + 1) / (diffusion_length - 1));
+  const float phase_log = logf((diffusion_length + 1) / (diffusion_length - 1));
 
   /* Modify state for RNGs, decorrelated from other paths. */
   rng_state.rng_hash = cmj_hash(rng_state.rng_hash + rng_state.rng_offset, 0xdeadbeef);
@@ -505,8 +513,7 @@ ccl_device_inline bool subsurface_random_walk(INTEGRATOR_STATE_ARGS)
     }
   }
 
-  kernel_assert(isfinite_safe(throughput.x) && isfinite_safe(throughput.y) &&
-                isfinite_safe(throughput.z));
+  kernel_assert(isfinite3_safe(throughput));
 
   /* Return number of hits in ss_isect. */
   if (!hit) {



More information about the Bf-blender-cvs mailing list