[Bf-blender-cvs] [e020820] soc-2016-cycles_denoising: Cycles: Implement multi-frame denoising buffers

Lukas Stockner noreply at git.blender.org
Sat Aug 13 05:12:38 CEST 2016


Commit: e0208200464f95533f9be128c5b5e43bc5bf6c8f
Author: Lukas Stockner
Date:   Sat Aug 13 04:06:26 2016 +0200
Branches: soc-2016-cycles_denoising
https://developer.blender.org/rBe0208200464f95533f9be128c5b5e43bc5bf6c8f

Cycles: Implement multi-frame denoising buffers

This commit changes the prefiltering code so that it processes all included frames.

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

M	intern/cycles/device/device_cpu.cpp
M	intern/cycles/render/session.cpp

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

diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 9ca1d03..8d77a52d 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -208,7 +208,7 @@ public:
 		}
 	};
 
-	float* denoise_fill_buffer(KernelGlobals *kg, int sample, int4 rect, float** buffers, int* tile_x, int* tile_y, int *offsets, int *strides)
+	float* denoise_fill_buffer(KernelGlobals *kg, int sample, int4 rect, float** buffers, int* tile_x, int* tile_y, int *offsets, int *strides, int frames, int *frame_strides)
 	{
 		void(*filter_divide_shadow)(KernelGlobals*, int, float**, int, int, int*, int*, int*, int*, float*, float*, float*, float*, int4);
 		void(*filter_get_feature)(KernelGlobals*, int, float**, int, int, int, int, int*, int*, int*, int*, float*, float*, int4);
@@ -268,144 +268,151 @@ public:
 		}
 
 		int w = align_up(rect.z - rect.x, 4), h = (rect.w - rect.y);
-		float *filter_buffer = new float[22*w*h];
+		int pass_stride = w*h*frames;
+		float *filter_buffers = new float[22*pass_stride];
 
 
-
-		/* ==== Step 1: Prefilter general features. ==== */
-		{
-			float *unfiltered = filter_buffer + 16*w*h;
-			/* Order in render buffers:
-			 *   Normal[X, Y, Z] NormalVar[X, Y, Z] Albedo[R, G, B] AlbedoVar[R, G, B ] Depth DepthVar
-			 *          0  1  2            3  4  5         6  7  8            9  10 11  12    13
-			 *
-			 * Order in denoise buffer:
-			 *   Normal[X, XVar, Y, YVar, Z, ZVar] Depth DepthVar Shadow ShadowVar Albedo[R, RVar, G, GVar, B, BVar] Color[R, RVar, G, GVar, B, BVar]
-			 *          0  1     2  3     4  5     6     7        8      9                10 11    12 13    14 15          16 17    18 19    20 21
-			 *
-			 * Order of processing: |NormalXYZ|Depth|AlbedoXYZ |
-			 *                      |         |     |          | */
-			int mean_from[]      = { 0, 1, 2,   6,    7,  8, 12 };
-			int variance_from[]  = { 3, 4, 5,   9,   10, 11, 13 };
-			int offset_to[]      = { 0, 2, 4,  10,   12, 14,  6 };
-			for(int i = 0; i < 7; i++) {
-				for(int y = rect.y; y < rect.w; y++) {
-					for(int x = rect.x; x < rect.z; x++) {
-						filter_get_feature(kg, sample, buffers, mean_from[i], variance_from[i], x, y, tile_x, tile_y, offsets, strides, unfiltered, filter_buffer + (offset_to[i]+1)*w*h, rect);
+		for(int frame = 0; frame < frames; frame++) {
+			float *filter_buffer = filter_buffers + w*h*frame;
+			float *buffer[9];
+			for(int i = 0; i < 9; i++) {
+				buffer[i] = buffers[i] + frame_strides[i]*frame;
+			}
+			/* ==== Step 1: Prefilter general features. ==== */
+			{
+				float *unfiltered = filter_buffer + 16*pass_stride;
+				/* Order in render buffers:
+				 *   Normal[X, Y, Z] NormalVar[X, Y, Z] Albedo[R, G, B] AlbedoVar[R, G, B ] Depth DepthVar
+				 *          0  1  2            3  4  5         6  7  8            9  10 11  12    13
+				 *
+				 * Order in denoise buffer:
+				 *   Normal[X, XVar, Y, YVar, Z, ZVar] Depth DepthVar Shadow ShadowVar Albedo[R, RVar, G, GVar, B, BVar] Color[R, RVar, G, GVar, B, BVar]
+				 *          0  1     2  3     4  5     6     7        8      9                10 11    12 13    14 15          16 17    18 19    20 21
+				 *
+				 * Order of processing: |NormalXYZ|Depth|AlbedoXYZ |
+				 *                      |         |     |          | */
+				int mean_from[]      = { 0, 1, 2,   6,    7,  8, 12 };
+				int variance_from[]  = { 3, 4, 5,   9,   10, 11, 13 };
+				int offset_to[]      = { 0, 2, 4,  10,   12, 14,  6 };
+				for(int i = 0; i < 7; i++) {
+					for(int y = rect.y; y < rect.w; y++) {
+						for(int x = rect.x; x < rect.z; x++) {
+							filter_get_feature(kg, sample, buffer, mean_from[i], variance_from[i], x, y, tile_x, tile_y, offsets, strides, unfiltered, filter_buffer + (offset_to[i]+1)*pass_stride, rect);
+						}
 					}
-				}
-				for(int y = rect.y; y < rect.w; y++) {
-					for(int x = rect.x; x < rect.z; x++) {
-						filter_non_local_means(x, y, unfiltered, unfiltered, filter_buffer + (offset_to[i]+1)*w*h, filter_buffer + offset_to[i]*w*h, rect, 2, 2, 1, 0.25f);
+					for(int y = rect.y; y < rect.w; y++) {
+						for(int x = rect.x; x < rect.z; x++) {
+							filter_non_local_means(x, y, unfiltered, unfiltered, filter_buffer + (offset_to[i]+1)*pass_stride, filter_buffer + offset_to[i]*pass_stride, rect, 2, 2, 1, 0.25f);
+						}
 					}
-				}
 #ifdef WITH_CYCLES_DEBUG_FILTER
 #define WRITE_DEBUG(name, var) debug_write_pfm(string_printf("debug_%dx%d_feature%d_%s.pfm", tile.x, tile.y, i, name).c_str(), var, w, h, 1, w)
-				WRITE_DEBUG("unfiltered", unfiltered);
-				WRITE_DEBUG("sampleV", filter_buffer + (offset_to[i]+1)*w*h);
-				WRITE_DEBUG("filtered", filter_buffer + offset_to[i]*w*h);
+					WRITE_DEBUG("unfiltered", unfiltered);
+					WRITE_DEBUG("sampleV", filter_buffer + (offset_to[i]+1)*pass_stride);
+					WRITE_DEBUG("filtered", filter_buffer + offset_to[i]*pass_stride);
 #undef WRITE_DEBUG
 #endif
+				}
 			}
-		}
 
 
 
-		/* ==== Step 2: Prefilter shadow feature. ==== */
-		{
-			/* Reuse some passes of the filter_buffer for temporary storage. */
-			float *sampleV = filter_buffer + 16*w*h, *sampleVV = filter_buffer + 17*w*h, *bufferV = filter_buffer + 18*w*h, *cleanV = filter_buffer + 19*w*h;
-			float *unfiltered = filter_buffer + 20*w*h;
-
-			/* Get the A/B unfiltered passes, the combined sample variance, the estimated variance of the sample variance and the buffer variance. */
-			for(int y = rect.y; y < rect.w; y++) {
-				for(int x = rect.x; x < rect.z; x++) {
-					filter_divide_shadow(kg, sample, buffers, x, y, tile_x, tile_y, offsets, strides, unfiltered, sampleV, sampleVV, bufferV, rect);
+			/* ==== Step 2: Prefilter shadow feature. ==== */
+			{
+				/* Reuse some passes of the filter_buffer for temporary storage. */
+				float *sampleV = filter_buffer + 16*pass_stride, *sampleVV = filter_buffer + 17*pass_stride, *bufferV = filter_buffer + 18*pass_stride, *cleanV = filter_buffer + 19*pass_stride;
+				float *unfiltered = filter_buffer + 20*pass_stride;
+
+				/* Get the A/B unfiltered passes, the combined sample variance, the estimated variance of the sample variance and the buffer variance. */
+				for(int y = rect.y; y < rect.w; y++) {
+					for(int x = rect.x; x < rect.z; x++) {
+						filter_divide_shadow(kg, sample, buffer, x, y, tile_x, tile_y, offsets, strides, unfiltered, sampleV, sampleVV, bufferV, rect);
+					}
 				}
-			}
 #ifdef WITH_CYCLES_DEBUG_FILTER
 #define WRITE_DEBUG(name, var) debug_write_pfm(string_printf("debug_%dx%d_shadow_%s.pfm", tile.x, tile.y, name).c_str(), var, w, h, 1, w)
-			WRITE_DEBUG("unfilteredA", unfiltered);
-			WRITE_DEBUG("unfilteredB", unfiltered + w*h);
-			WRITE_DEBUG("bufferV", bufferV);
-			WRITE_DEBUG("sampleV", sampleV);
-			WRITE_DEBUG("sampleVV", sampleVV);
+				WRITE_DEBUG("unfilteredA", unfiltered);
+				WRITE_DEBUG("unfilteredB", unfiltered + pass_stride);
+				WRITE_DEBUG("bufferV", bufferV);
+				WRITE_DEBUG("sampleV", sampleV);
+				WRITE_DEBUG("sampleVV", sampleVV);
 #endif
 
-			/* Smooth the (generally pretty noisy) buffer variance using the spatial information from the sample variance. */
-			for(int y = rect.y; y < rect.w; y++) {
-				for(int x = rect.x; x < rect.z; x++) {
-					filter_non_local_means(x, y, bufferV, sampleV, sampleVV, cleanV, rect, 3, 1, 4, 1.0f);
+				/* Smooth the (generally pretty noisy) buffer variance using the spatial information from the sample variance. */
+				for(int y = rect.y; y < rect.w; y++) {
+					for(int x = rect.x; x < rect.z; x++) {
+						filter_non_local_means(x, y, bufferV, sampleV, sampleVV, cleanV, rect, 3, 1, 4, 1.0f);
+					}
 				}
-			}
 #ifdef WITH_CYCLES_DEBUG_FILTER
-		WRITE_DEBUG("cleanV", cleanV);
+			WRITE_DEBUG("cleanV", cleanV);
 #endif
 
-			/* Use the smoothed variance to filter the two shadow half images using each other for weight calculation. */
-			for(int y = rect.y; y < rect.w; y++) {
-				for(int x = rect.x; x < rect.z; x++) {
-					filter_non_local_means(x, y, unfiltered, unfiltered + w*h, cleanV, sampleV, rect, 5, 3, 1, 0.25f);
-					filter_non_local_means(x, y, unfiltered + w*h, unfiltered, cleanV, bufferV, rect, 5, 3, 1, 0.25f);
+				/* Use the smoothed variance to filter the two shadow half images using each other for weight calculation. */
+				for(int y = rect.y; y < rect.w; y++) {
+					for(int x = rect.x; x < rect.z; x++) {
+						filter_non_local_means(x, y, unfiltered, unfiltered + pass_stride, cleanV, sampleV, rect, 5, 3, 1, 0.25f);
+						filter_non_local_means(x, y, unfiltered + pass_stride, unfiltered, cleanV, bufferV, rect, 5, 3, 1, 0.25f);
+					}
 				}
-			}
 #ifdef WITH_CYCLES_DEBUG_FILTER
-			WRITE_DEBUG("filteredA", sampleV);
-			WRITE_DEBUG("filteredB", bufferV);
+				WRITE_DEBUG("filteredA", sampleV);
+				WRITE_DEBUG("filteredB", bufferV);
 #endif
 
-			/* Estimate the residual variance between the two filtered halves. */
-			for(int y = rect.y; y < rect.w; y++) {
-				for(int x = rect.x; x < rect.z; x++) {
-					filter_combine_halves(x, y, NULL, sampleVV, sampleV, bufferV, rect);
+				/* Estimate the residual variance between the two filtered halves. */
+				for(int y = rect.y; y < rect.w; y++) {
+					for(int x = rect.x; x < rect.z; x++) {
+						filter_combine_halves(x, y, NULL, sampleVV, sampleV, bufferV, rect);
+					}
 				}
-			}
 #ifdef WITH_CYCLES_DEBUG_FILTER
-			WRITE_DEBUG("residualV", sampleVV);
+				WRITE_DEBUG("residualV", sampleVV);
 #endif
 
-			/* Use the residual variance for a second filter pass. */
-			for(int y = rect.y; y < rect.w; y++) {
-				for(int x = rect.x; x < rect.z; x++) {
-					filter_non_local_means(x, y, sampleV, bufferV, sampleVV, unfiltered      , rect, 4, 2, 1, 0.25f);
-					filter_non_local_means(x, y, bufferV, sampleV, sampleVV, unfiltered + w*h, rect, 4, 2, 1, 0.25f);
+				/* Use the residual variance for a second filter pass. */
+				for(int y = rect.y; y < rect.w; y++) {
+					for(int x = rect.x; x < rect.z; x++) {
+						filter_non_local_means(x, y, sampleV, bufferV, sampleVV, unfiltered      , rect, 4, 2, 1, 0.25f);
+						filter_non_local_means(x, y, bufferV, sampleV, sampleVV, unfiltered + pass_stride, rect, 4, 2, 1, 0.25f);
+					}
 				}
-			}
 #ifdef WITH_CYCLES_DEBUG_FILTER
-			WRITE_DEBUG("

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list