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
path: root/intern
diff options
context:
space:
mode:
authorLukas Stockner <lukas.stockner@freenet.de>2017-06-11 02:44:06 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2017-06-11 02:51:39 +0300
commit558bea225296751b849572122d6202b4ab1fa1cf (patch)
tree03a7269235f5055b70ab2f292c3900fd2e22904c /intern
parent0dd6e5bfee3dee0ced75e9cb03e950627b59e75e (diff)
Cycles Denoising: Add more failsafes for invalid pixels
Now, when there is no usable neighboring pixel for denoising, the noisy value is preserved instead of producing a NaN. Also, negative results are clamped to zero. Note that there are just workarounds that don't fix the underlying problems, but these issues are very rare and I'm not sure if it's even possible to fix the underlying problems without introducing a significant slowdown or quality decrease in other situations. Because of that and since 2.79 is happening very soon, I just went for these workarounds for now.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/filter/filter_reconstruction.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/intern/cycles/kernel/filter/filter_reconstruction.h b/intern/cycles/kernel/filter/filter_reconstruction.h
index d6d7639a22d..25a3025056c 100644
--- a/intern/cycles/kernel/filter/filter_reconstruction.h
+++ b/intern/cycles/kernel/filter/filter_reconstruction.h
@@ -81,6 +81,12 @@ ccl_device_inline void kernel_filter_finalize(int x, int y, int w, int h,
(void) storage_stride;
#endif
+ if(XtWX[0] < 1e-3f) {
+ /* There is not enough information to determine a denoised result.
+ * As a fallback, keep the original value of the pixel. */
+ return;
+ }
+
/* The weighted average of pixel colors (essentially, the NLM-filtered image).
* In case the solution of the linear model fails due to numerical issues,
* fall back to this value. */
@@ -93,6 +99,9 @@ ccl_device_inline void kernel_filter_finalize(int x, int y, int w, int h,
final_color = mean_color;
}
+ /* Clamp pixel value to positive values. */
+ final_color = max(final_color, make_float3(0.0f, 0.0f, 0.0f));
+
ccl_global float *combined_buffer = buffer + (y*buffer_params.y + x + buffer_params.x)*buffer_params.z;
final_color *= sample;
if(buffer_params.w) {