diff options
-rw-r--r-- | intern/cycles/kernel/filter/filter_reconstruction.h | 8 | ||||
-rw-r--r-- | intern/cycles/util/util_math_float3.h | 5 |
2 files changed, 13 insertions, 0 deletions
diff --git a/intern/cycles/kernel/filter/filter_reconstruction.h b/intern/cycles/kernel/filter/filter_reconstruction.h index 13e90f8233b..dc90f318570 100644 --- a/intern/cycles/kernel/filter/filter_reconstruction.h +++ b/intern/cycles/kernel/filter/filter_reconstruction.h @@ -85,9 +85,17 @@ ccl_device_inline void kernel_filter_finalize(int x, int y, int w, int h, const int stride = storage_stride; #endif + /* 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. */ + float3 mean_color = XtWY[0]/XtWX[0]; + math_trimatrix_vec3_solve(XtWX, XtWY, (*rank)+1, stride); float3 final_color = XtWY[0]; + if(!isfinite3_safe(final_color)) { + final_color = mean_color; + } ccl_global float *combined_buffer = buffer + (y*buffer_params.y + x + buffer_params.x)*buffer_params.z; final_color *= sample; diff --git a/intern/cycles/util/util_math_float3.h b/intern/cycles/util/util_math_float3.h index a754be413fe..5327d9f7cc6 100644 --- a/intern/cycles/util/util_math_float3.h +++ b/intern/cycles/util/util_math_float3.h @@ -367,6 +367,11 @@ ccl_device_inline bool isequal_float3(const float3 a, const float3 b) #endif } +ccl_device_inline bool isfinite3_safe(float3 v) +{ + return isfinite_safe(v.x) && isfinite_safe(v.y) && isfinite_safe(v.z); +} + ccl_device_inline float3 ensure_finite3(float3 v) { if(!isfinite_safe(v.x)) v.x = 0.0; |