[Bf-blender-cvs] [c183ac73dcf] blender2.7: Cycles: tweak outlier detection, preparing for animation denoising.

Lukas Stockner noreply at git.blender.org
Wed Feb 6 15:20:16 CET 2019


Commit: c183ac73dcfd20d0acf5ca07a2b062deadc4d73a
Author: Lukas Stockner
Date:   Wed Feb 6 14:42:32 2019 +0100
Branches: blender2.7
https://developer.blender.org/rBc183ac73dcfd20d0acf5ca07a2b062deadc4d73a

Cycles: tweak outlier detection, preparing for animation denoising.

Ref D3889.

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

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 41be4dbea49..e24f4feb28d 100644
--- a/intern/cycles/kernel/filter/filter_prefilter.h
+++ b/intern/cycles/kernel/filter/filter_prefilter.h
@@ -140,6 +140,7 @@ ccl_device void kernel_filter_detect_outliers(int x, int y,
 
 	int n = 0;
 	float values[25];
+	float pixel_variance, max_variance = 0.0f;
 	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);
@@ -159,15 +160,31 @@ ccl_device void kernel_filter_detect_outliers(int x, int y,
 			/* Insert L. */
 			values[i] = L;
 			n++;
+
+			float3 pixel_var = make_float3(variance[idx], variance[idx+pass_stride], variance[idx+2*pass_stride]);
+			float var = average(pixel_var);
+			if((x1 == x) && (y1 == y)) {
+				pixel_variance = (pixel_var.x < 0.0f || pixel_var.y < 0.0f || pixel_var.z < 0.0f)? -1.0f : var;
+			}
+			else {
+				max_variance = max(max_variance, var);
+			}
 		}
 	}
 
+	max_variance += 1e-4f;
+
 	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)];
+
+	/* Slightly offset values to avoid false positives in (almost) black areas. */
+	max_variance += 1e-5f;
+	ref -= 1e-5f;
+
 	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
@@ -175,16 +192,24 @@ ccl_device void kernel_filter_detect_outliers(int x, int y,
 		 * 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. */
+
+		if(pixel_variance < 0.0f || pixel_variance > 9.0f * max_variance) {
 			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;
+			color *= ref/L;
+			variance[idx] = variance[idx + pass_stride] = variance[idx + 2*pass_stride] = max_variance;
+		}
+		else {
+			float stddev = sqrtf(pixel_variance);
+			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              ] = color.x;



More information about the Bf-blender-cvs mailing list