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. @@

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

Reply via email to