Commit: f9a3d01452e9991774fbdf5669015953a3c23805
Author: Lukas Stockner
Date:   Thu Aug 24 23:15:30 2017 +0200
Branches: master
https://developer.blender.org/rBf9a3d01452e9991774fbdf5669015953a3c23805

Cycles: Mark pixels with negative values as outliers

If a pixel has negative components, something already went wrong, so the best 
option is to just ignore it.

Should be good for 2.79.

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

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 c6a70cbeab5..2aeb54a62be 100644
--- a/intern/cycles/kernel/filter/filter_prefilter.h
+++ b/intern/cycles/kernel/filter/filter_prefilter.h
@@ -120,49 +120,56 @@ ccl_device void kernel_filter_detect_outliers(int x, int 
y,
 {
        int buffer_w = align_up(rect.z - rect.x, 4);
 
-       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 idx = (y-rect.y)*buffer_w + (x-rect.x);
-       float L = average(make_float3(image[idx], image[idx+pass_stride], 
image[idx+2*pass_stride]));
+       float3 color = make_float3(image[idx], image[idx+pass_stride], 
image[idx+2*pass_stride]);
 
-       float ref = 2.0f*values[(int)(n*0.75f)];
        float fac = 1.0f;
-       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;
+       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++;
+                       }
+               }
+
+               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;
+                       }
                }
        }
        out[idx              ] = fac*image[idx];

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

Reply via email to