Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey@blender.org>2021-09-16 17:12:08 +0300
committerSergey Sharybin <sergey@blender.org>2021-09-17 11:25:44 +0300
commitd80d23e542f1e49d827f77b29e107057c1bc9a58 (patch)
treeb2c9276e9c9455818dc5f2a47ed6f620b1be2141
parent85f060dc94f141c195ec01fe68725807f4eb7908 (diff)
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
-rw-r--r--intern/cycles/kernel/kernel_film.h42
1 files changed, 36 insertions, 6 deletions
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;