Commit: bf1dc3967971c882a9179d31a36f03702cbc8e0f
Author: Lukas Stockner
Date:   Thu Dec 21 14:24:23 2017 +0100
Branches: master
https://developer.blender.org/rBbf1dc3967971c882a9179d31a36f03702cbc8e0f

Fix T53567: Negative pixel values causing artifacts with denoising

Now negative color values are clamped to zero before the actual denoising.

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

M       intern/cycles/kernel/filter/filter_prefilter.h

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

diff --git a/intern/cycles/kernel/filter/filter_prefilter.h 
b/intern/cycles/kernel/filter/filter_prefilter.h
index eefcbfea230..4af209341f6 100644
--- a/intern/cycles/kernel/filter/filter_prefilter.h
+++ b/intern/cycles/kernel/filter/filter_prefilter.h
@@ -117,61 +117,58 @@ ccl_device void kernel_filter_detect_outliers(int x, int 
y,
 {
        int buffer_w = align_up(rect.z - rect.x, 4);
 
-       int idx = (y-rect.y)*buffer_w + (x-rect.x);
-       float3 color = make_float3(image[idx], image[idx+pass_stride], 
image[idx+2*pass_stride]);
-
-       float fac = 1.0f;
-       if(color.x < 0.0f || color.y < 0.0f || color.z < 0.0f) {
-               depth[idx] = -depth[idx];
-               fac = 0.0f;
-       }
-       else {
-               float L = average(color);
-               int n = 0;
-               float values[25];
-               for(int y1 = max(y-2, rect.y); y1 < min(y+3, rect.w); y1++) {
-                       for(int x1 = max(x-2, rect.x); x1 < min(x+3, rect.z); 
x1++) {
-                               int idx = (y1-rect.y)*buffer_w + (x1-rect.x);
-                               float L = average(make_float3(image[idx], 
image[idx+pass_stride], image[idx+2*pass_stride]));
-
-                               /* Find the position of L. */
-                               int i;
-                               for(i = 0; i < n; i++) {
-                                       if(values[i] > L) break;
-                               }
-                               /* Make space for L by shifting all following 
values to the right. */
-                               for(int j = n; j > i; j--) {
-                                       values[j] = values[j-1];
-                               }
-                               /* Insert L. */
-                               values[i] = L;
-                               n++;
+       int n = 0;
+       float values[25];
+       for(int y1 = max(y-2, rect.y); y1 < min(y+3, rect.w); y1++) {
+               for(int x1 = max(x-2, rect.x); x1 < min(x+3, rect.z); x1++) {
+                       int idx = (y1-rect.y)*buffer_w + (x1-rect.x);
+                       float3 color = make_float3(image[idx], 
image[idx+pass_stride], image[idx+2*pass_stride]);
+                       color = max(color, make_float3(0.0f, 0.0f, 0.0f));
+                       float L = average(color);
+
+                       /* Find the position of L. */
+                       int i;
+                       for(i = 0; i < n; i++) {
+                               if(values[i] > L) break;
+                       }
+                       /* Make space for L by shifting all following values to 
the right. */
+                       for(int j = n; j > i; j--) {
+                               values[j] = values[j-1];
                        }
+                       /* Insert L. */
+                       values[i] = L;
+                       n++;
                }
+       }
 
-               float ref = 2.0f*values[(int)(n*0.75f)];
-               if(L > ref) {
-                       /* The pixel appears to be an outlier.
-                        * However, it may just be a legitimate highlight. 
Therefore, it is checked how likely it is that the pixel
-                        * should actually be at the reference value:
-                        * If the reference is within the 3-sigma interval, the 
pixel is assumed to be a statistical outlier.
-                        * Otherwise, it is very unlikely that the pixel should 
be darker, which indicates a legitimate highlight.
-                        */
-                       float stddev = sqrtf(average(make_float3(variance[idx], 
variance[idx+pass_stride], variance[idx+2*pass_stride])));
-                       if(L - 3*stddev < ref) {
-                               /* The pixel is an outlier, so negate the depth 
value to mark it as one.
-                                * Also, scale its brightness down to the 
outlier threshold to avoid trouble with the NLM weights. */
-                               depth[idx] = -depth[idx];
-                               fac = ref/L;
-                               variance[idx              ] *= fac*fac;
-                               variance[idx + pass_stride] *= fac*fac;
-                               variance[idx+2*pass_stride] *= fac*fac;
-                       }
+       int idx = (y-rect.y)*buffer_w + (x-rect.x);
+       float3 color = make_float3(image[idx], image[idx+pass_stride], 
image[idx+2*pass_stride]);
+       color = max(color, make_float3(0.0f, 0.0f, 0.0f));
+       float L = average(color);
+
+       float ref = 2.0f*values[(int)(n*0.75f)];
+       if(L > ref) {
+               /* The pixel appears to be an outlier.
+                * However, it may just be a legitimate highlight. Therefore, 
it is checked how likely it is that the pixel
+                * should actually be at the reference value:
+                * If the reference is within the 3-sigma interval, the pixel 
is assumed to be a statistical outlier.
+                * Otherwise, it is very unlikely that the pixel should be 
darker, which indicates a legitimate highlight.
+                */
+               float stddev = sqrtf(average(make_float3(variance[idx], 
variance[idx+pass_stride], variance[idx+2*pass_stride])));
+               if(L - 3*stddev < ref) {
+                       /* The pixel is an outlier, so negate the depth value 
to mark it as one.
+                        * Also, scale its brightness down to the outlier 
threshold to avoid trouble with the NLM weights. */
+                       depth[idx] = -depth[idx];
+                       float fac = ref/L;
+                       color *= fac;
+                       variance[idx              ] *= fac*fac;
+                       variance[idx + pass_stride] *= fac*fac;
+                       variance[idx+2*pass_stride] *= fac*fac;
                }
        }
-       out[idx              ] = fac*image[idx];
-       out[idx + pass_stride] = fac*image[idx + pass_stride];
-       out[idx+2*pass_stride] = fac*image[idx+2*pass_stride];
+       out[idx              ] = color.x;
+       out[idx + pass_stride] = color.y;
+       out[idx+2*pass_stride] = color.z;
 }
 
 /* Combine A/B buffers.

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to