[Bf-blender-cvs] [26fb2fabcd] temp-cycles-denoising: Cycles Denoising: Fix variance pass generation in the split kernel

Lukas Stockner noreply at git.blender.org
Fri Mar 24 20:18:33 CET 2017


Commit: 26fb2fabcd59e126c60e020c328eb8eb94791242
Author: Lukas Stockner
Date:   Sun Mar 19 00:28:01 2017 +0100
Branches: temp-cycles-denoising
https://developer.blender.org/rB26fb2fabcd59e126c60e020c328eb8eb94791242

Cycles Denoising: Fix variance pass generation in the split kernel

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

M	intern/cycles/device/device_cpu.cpp
M	intern/cycles/device/device_cuda.cpp
M	intern/cycles/device/device_denoising.h
M	intern/cycles/filter/filter_prefilter.h
M	intern/cycles/filter/kernels/cpu/filter_cpu.h
M	intern/cycles/filter/kernels/cpu/filter_cpu_impl.h
M	intern/cycles/filter/kernels/cuda/filter.cu
M	intern/cycles/kernel/kernel_passes.h

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

diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index efc6aeb76c..5f25ede516 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -174,10 +174,10 @@ public:
 	KernelFunctions<void(*)(KernelGlobals *, uchar4 *, float *, float, int, int, int, int)>       convert_to_byte_kernel;
 	KernelFunctions<void(*)(KernelGlobals *, uint4 *, float4 *, float*, int, int, int, int, int)> shader_kernel;
 
-	KernelFunctions<void(*)(int, TilesInfo*, int, int, float*, float*, float*, float*, float*, int*, int, int, bool)> filter_divide_shadow_kernel;
-	KernelFunctions<void(*)(int, TilesInfo*, int, int, int, int, float*, float*, int*, int, int, bool)>               filter_get_feature_kernel;
-	KernelFunctions<void(*)(int, int, float*, float*, float*, float*, int*, int)>                                     filter_combine_halves_kernel;
-	KernelFunctions<void(*)(int, int, int, float*, int, int, int, int)>                                               filter_divide_combined_kernel;
+	KernelFunctions<void(*)(int, TilesInfo*, int, int, float*, float*, float*, float*, float*, int*, int, int, bool, bool)> filter_divide_shadow_kernel;
+	KernelFunctions<void(*)(int, TilesInfo*, int, int, int, int, float*, float*, int*, int, int, bool, bool)>               filter_get_feature_kernel;
+	KernelFunctions<void(*)(int, int, float*, float*, float*, float*, int*, int)>                                           filter_combine_halves_kernel;
+	KernelFunctions<void(*)(int, int, int, float*, int, int, int, int)>                                                     filter_divide_combined_kernel;
 
 	KernelFunctions<void(*)(int, int, float*, float*, float*, int*, int, int, float, float)> filter_nlm_calc_difference_kernel;
 	KernelFunctions<void(*)(float*, float*, int*, int, int)>                                 filter_nlm_blur_kernel;
@@ -553,7 +553,8 @@ public:
 				                              &task->rect.x,
 				                              task->render_buffer.pass_stride,
 				                              task->render_buffer.denoising_data_offset,
-				                              task->use_gradients);
+				                              task->use_gradients,
+				                              task->use_split_variance);
 			}
 		}
 		return true;
@@ -577,7 +578,8 @@ public:
 				                            &task->rect.x,
 				                            task->render_buffer.pass_stride,
 				                            task->render_buffer.denoising_data_offset,
-				                            task->use_cross_denoising);
+				                            task->use_cross_denoising,
+				                            task->use_split_variance);
 			}
 		}
 		return true;
@@ -622,6 +624,7 @@ public:
 		DenoisingTask denoising(this);
 		denoising.filter_area = make_int4(tile.x, tile.y, tile.w, tile.h);
 		denoising.render_buffer.samples = tile.sample;
+		denoising.use_split_variance = use_split_kernel;
 
 		RenderTile rtiles[9];
 		rtiles[4] = tile;
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index bdabc29d84..ce9057e75c 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -1182,7 +1182,8 @@ public:
 		                &task->rect,
 		                &task->render_buffer.pass_stride,
 		                &task->render_buffer.denoising_data_offset,
-		                &task->use_gradients};
+		                &task->use_gradients,
+		                &task->use_split_variance};
 		CUDA_LAUNCH_KERNEL(cuFilterDivideShadow, args);
 		cuda_assert(cuCtxSynchronize());
 
@@ -1217,7 +1218,8 @@ public:
 		                &task->rect,
 		                &task->render_buffer.pass_stride,
 		                &task->render_buffer.denoising_data_offset,
-		                &task->use_cross_denoising};
+		                &task->use_cross_denoising,
+		                &task->use_split_variance};
 		CUDA_LAUNCH_KERNEL(cuFilterGetFeature, args);
 		cuda_assert(cuCtxSynchronize());
 
diff --git a/intern/cycles/device/device_denoising.h b/intern/cycles/device/device_denoising.h
index 07dac7087b..d61c0ba880 100644
--- a/intern/cycles/device/device_denoising.h
+++ b/intern/cycles/device/device_denoising.h
@@ -32,6 +32,7 @@ public:
 	float nlm_k_2;
 	bool use_cross_denoising;
 	bool use_gradients;
+	bool use_split_variance;
 
 	/* Pointer and parameters of the RenderBuffers. */
 	struct RenderBuffers {
diff --git a/intern/cycles/filter/filter_prefilter.h b/intern/cycles/filter/filter_prefilter.h
index 16c11b0f44..5024873cee 100644
--- a/intern/cycles/filter/filter_prefilter.h
+++ b/intern/cycles/filter/filter_prefilter.h
@@ -36,7 +36,8 @@ ccl_device void kernel_filter_divide_shadow(int sample,
                                             int4 rect,
                                             int buffer_pass_stride,
                                             int buffer_denoising_offset,
-                                            bool use_gradients)
+                                            bool use_gradients,
+                                            bool use_split_variance)
 {
 	int xtile = (x < tiles->x[1])? 0: ((x < tiles->x[2])? 1: 2);
 	int ytile = (y < tiles->y[1])? 0: ((y < tiles->y[2])? 1: 2);
@@ -52,10 +53,22 @@ ccl_device void kernel_filter_divide_shadow(int sample,
 	int idx = (y-rect.y)*buffer_w + (x - rect.x);
 	unfilteredA[idx] = center_buffer[15] / max(center_buffer[14], 1e-7f);
 	unfilteredB[idx] = center_buffer[18] / max(center_buffer[17], 1e-7f);
-	float varFac = 1.0f / (sample * (sample-1));
-	sampleVariance[idx] = (center_buffer[16] + center_buffer[19]) * varFac;
-	sampleVarianceV[idx] = 0.5f * (center_buffer[16] - center_buffer[19]) * (center_buffer[16] - center_buffer[19]) * varFac * varFac;
-	bufferVariance[idx] = 0.5f * (unfilteredA[idx] - unfilteredB[idx]) * (unfilteredA[idx] - unfilteredB[idx]);
+
+	float varA, varB;
+	int odd_sample = (sample+1)/2;
+	int even_sample = sample/2;
+	if(use_split_variance) {
+		varA = (center_buffer[16] - unfilteredA[idx]*unfilteredA[idx]*odd_sample) / (odd_sample - 1);
+		varB = (center_buffer[19] - unfilteredB[idx]*unfilteredB[idx]*even_sample) / (even_sample - 1);
+	}
+	else {
+		varA = center_buffer[16] / (odd_sample - 1);
+		varB = center_buffer[19] / (even_sample - 1);
+	}
+
+	sampleVariance[idx]  = 0.5f*(varA + varB) / sample;
+	sampleVarianceV[idx] = 0.5f * (varA - varB) * (varA - varB) / (sample*sample);
+	bufferVariance[idx]  = 0.5f * (unfilteredA[idx] - unfilteredB[idx]) * (unfilteredA[idx] - unfilteredB[idx]);
 }
 
 /* Load a regular feature from the render buffers into the denoise buffer.
@@ -72,7 +85,8 @@ ccl_device void kernel_filter_get_feature(int sample,
                                           int x, int y,
                                           float *mean, float *variance,
                                           int4 rect, int buffer_pass_stride,
-                                          int buffer_denoising_offset, bool use_cross_denoising)
+                                          int buffer_denoising_offset, bool use_cross_denoising,
+                                          bool use_split_variance)
 {
 	int xtile = (x < tiles->x[1])? 0: ((x < tiles->x[2])? 1: 2);
 	int ytile = (y < tiles->y[1])? 0: ((y < tiles->y[2])? 1: 2);
@@ -86,16 +100,31 @@ ccl_device void kernel_filter_get_feature(int sample,
 	if(m_offset >= 20 && m_offset <= 22 && use_cross_denoising) {
 		int odd_sample = sample/2;
 		mean[idx] = (center_buffer[m_offset] - center_buffer[m_offset+6]) / odd_sample;
-		variance[idx] = center_buffer[v_offset] / (odd_sample * (sample-1));
+		if(use_split_variance) {
+			variance[idx] = (center_buffer[v_offset] - center_buffer[m_offset]/sample) / (odd_sample * (sample-1));
+		}
+		else {
+			variance[idx] = center_buffer[v_offset] / (odd_sample * (sample-1));
+		}
 	}
 	else if(m_offset >= 26) {
 		int even_sample = (sample+1)/2;
 		mean[idx] = center_buffer[m_offset] / even_sample;
-		variance[idx] = center_buffer[v_offset-6] / (even_sample * (sample-1));
+		if(use_split_variance) {
+			variance[idx] = (center_buffer[v_offset-6] - center_buffer[m_offset-6]/sample) / (even_sample * (sample-1));
+		}
+		else {
+			variance[idx] = center_buffer[v_offset-6] / (even_sample * (sample-1));
+		}
 	}
 	else {
 		mean[idx] = center_buffer[m_offset] / sample;
-		variance[idx] = center_buffer[v_offset] / (sample * (sample-1));
+		if(use_split_variance) {
+			variance[idx] = (center_buffer[v_offset] - mean[idx]) / (sample * (sample-1));
+		}
+		else {
+			variance[idx] = center_buffer[v_offset] / (sample * (sample-1));
+		}
 	}
 }
 
diff --git a/intern/cycles/filter/kernels/cpu/filter_cpu.h b/intern/cycles/filter/kernels/cpu/filter_cpu.h
index 349437a22f..5ad4ba215a 100644
--- a/intern/cycles/filter/kernels/cpu/filter_cpu.h
+++ b/intern/cycles/filter/kernels/cpu/filter_cpu.h
@@ -28,7 +28,8 @@ void KERNEL_FUNCTION_FULL_NAME(filter_divide_shadow)(int sample,
                                                      int* prefilter_rect,
                                                      int buffer_pass_stride,
                                                      int buffer_denoising_offset,
-                                                     bool use_gradients);
+                                                     bool use_gradients,
+                                                     bool use_split_variance);
 
 void KERNEL_FUNCTION_FULL_NAME(filter_get_feature)(int sample,
                                                    TilesInfo *tiles,
@@ -41,7 +42,8 @@ void KERNEL_FUNCTION_FULL_NAME(filter_get_feature)(int sample,
                                                    int* prefilter_rect,
                                                    int buffer_pass_stride,
                                                    int buffer_denoising_offset,
-                                                   bool use_cross_denoising);
+                                                   bool use_cross_denoising,
+                                                   bool use_split_variance);
 
 void KERNEL_FUNCTION_FULL_NAME(filter_combine_halves)(int x, int y,
               

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list