[Bf-blender-cvs] [d80d23e542f] cycles-x: Fix pass accessor with 0 samples

Sergey Sharybin noreply at git.blender.org
Fri Sep 17 10:35:11 CEST 2021


Commit: d80d23e542f1e49d827f77b29e107057c1bc9a58
Author: Sergey Sharybin
Date:   Thu Sep 16 16:12:08 2021 +0200
Branches: cycles-x
https://developer.blender.org/rBd80d23e542f1e49d827f77b29e107057c1bc9a58

Fix pass accessor with 0 samples

Avoid division by zero when calculating scale, and avoid multiplication
by inf later on.

The pixel processing functions are changed so that they return fully
transparent pixel for pixels where number of samples is 0. This allows
to have matched behavior of non-finished tiles with master, without
relying on non-finite math.

The extra condition when calculating scale is inevitable, and hopefully
the pixel processing function's if statement gets folded into it as
well ()due to force-inline).

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

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

M	intern/cycles/kernel/kernel_film.h

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

diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h
index db963db26bb..fa93f4830d1 100644
--- a/intern/cycles/kernel/kernel_film.h
+++ b/intern/cycles/kernel/kernel_film.h
@@ -62,7 +62,7 @@ ccl_device_inline float film_get_scale_exposure(const KernelFilmConvert *ccl_res
   return scale;
 }
 
-ccl_device_inline void film_get_scale_and_scale_exposure(
+ccl_device_inline bool film_get_scale_and_scale_exposure(
     const KernelFilmConvert *ccl_restrict kfilm_convert,
     ccl_global const float *ccl_restrict buffer,
     float *ccl_restrict scale,
@@ -71,11 +71,17 @@ ccl_device_inline void film_get_scale_and_scale_exposure(
   if (kfilm_convert->pass_sample_count == PASS_UNUSED) {
     *scale = kfilm_convert->scale;
     *scale_exposure = kfilm_convert->scale_exposure;
-    return;
+    return true;
+  }
+
+  const uint sample_count = *((const uint *)(buffer + kfilm_convert->pass_sample_count));
+  if (!sample_count) {
+    *scale = 0.0f;
+    *scale_exposure = 0.0f;
+    return false;
   }
 
   if (kfilm_convert->pass_use_filter) {
-    const uint sample_count = *((const uint *)(buffer + kfilm_convert->pass_sample_count));
     *scale = 1.0f / sample_count;
   }
   else {
@@ -88,6 +94,8 @@ ccl_device_inline void film_get_scale_and_scale_exposure(
   else {
     *scale_exposure = *scale;
   }
+
+  return true;
 }
 
 /* --------------------------------------------------------------------
@@ -303,8 +311,28 @@ ccl_device_inline void film_get_pass_pixel_combined(const KernelFilmConvert *ccl
   kernel_assert(kfilm_convert->num_components == 4);
 
   /* 3rd channel contains transparency = 1 - alpha for the combined pass. */
-  film_get_pass_pixel_float4(kfilm_convert, buffer, pixel);
-  pixel[3] = film_transparency_to_alpha(pixel[3]);
+
+  kernel_assert(kfilm_convert->num_components == 4);
+  kernel_assert(kfilm_convert->pass_offset != PASS_UNUSED);
+
+  float scale, scale_exposure;
+  if (!film_get_scale_and_scale_exposure(kfilm_convert, buffer, &scale, &scale_exposure)) {
+    pixel[0] = 0.0f;
+    pixel[1] = 0.0f;
+    pixel[2] = 0.0f;
+    pixel[3] = 0.0f;
+    return;
+  }
+
+  const float *in = buffer + kfilm_convert->pass_offset;
+
+  const float3 color = make_float3(in[0], in[1], in[2]) * scale_exposure;
+  const float alpha = in[3] * scale;
+
+  pixel[0] = color.x;
+  pixel[1] = color.y;
+  pixel[2] = color.z;
+  pixel[3] = film_transparency_to_alpha(alpha);
 }
 
 /* --------------------------------------------------------------------
@@ -417,7 +445,9 @@ ccl_device_inline float4 film_calculate_shadow_catcher_matte_with_shadow(
   kernel_assert(kfilm_convert->pass_shadow_catcher_matte != PASS_UNUSED);
 
   float scale, scale_exposure;
-  film_get_scale_and_scale_exposure(kfilm_convert, buffer, &scale, &scale_exposure);
+  if (!film_get_scale_and_scale_exposure(kfilm_convert, buffer, &scale, &scale_exposure)) {
+    return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+  }
 
   ccl_global const float *in_matte = buffer + kfilm_convert->pass_shadow_catcher_matte;



More information about the Bf-blender-cvs mailing list