forked from bartvdbraak/blender
Fix T51560: Black pixels on a denoising render
Once again, numerical instabilities causing the Cholesky decomposition to fail. However, further increasing the diagonal correction just because of a few pixels in very specific scenes and settings seems unjustified. Therefore, this commit simply falls back to the basic NLM-filtered pixel if the more advanced model fails.
This commit is contained in:
parent
177385dc43
commit
3dee1f079f
@ -85,9 +85,17 @@ ccl_device_inline void kernel_filter_finalize(int x, int y, int w, int h,
|
|||||||
const int stride = storage_stride;
|
const int stride = storage_stride;
|
||||||
#endif
|
#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);
|
math_trimatrix_vec3_solve(XtWX, XtWY, (*rank)+1, stride);
|
||||||
|
|
||||||
float3 final_color = XtWY[0];
|
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;
|
ccl_global float *combined_buffer = buffer + (y*buffer_params.y + x + buffer_params.x)*buffer_params.z;
|
||||||
final_color *= sample;
|
final_color *= sample;
|
||||||
|
@ -367,6 +367,11 @@ ccl_device_inline bool isequal_float3(const float3 a, const float3 b)
|
|||||||
#endif
|
#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)
|
ccl_device_inline float3 ensure_finite3(float3 v)
|
||||||
{
|
{
|
||||||
if(!isfinite_safe(v.x)) v.x = 0.0;
|
if(!isfinite_safe(v.x)) v.x = 0.0;
|
||||||
|
Loading…
Reference in New Issue
Block a user