Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-03-04 18:01:11 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-03-04 18:06:56 +0300
commite53db8342a9793954138173d8e1fdbcaa41d0009 (patch)
tree2eabfebe189a39941c960df6e250be78b0880c9e /intern/cycles/render/denoising.cpp
parentd3306f0272f02b98fc853f4eb8fb17a883f3ebdf (diff)
Fix Cycles animation denoising giving black pixels for some outliers.
The denoising code expects the output buffer to be filled with the noisy image, which was not the case for standalone denoising.
Diffstat (limited to 'intern/cycles/render/denoising.cpp')
-rw-r--r--intern/cycles/render/denoising.cpp46
1 files changed, 38 insertions, 8 deletions
diff --git a/intern/cycles/render/denoising.cpp b/intern/cycles/render/denoising.cpp
index a89cb97c4d8..ab74fd8fd38 100644
--- a/intern/cycles/render/denoising.cpp
+++ b/intern/cycles/render/denoising.cpp
@@ -123,16 +123,23 @@ static void fill_mapping(vector<ChannelMapping> &map, int pos, string name, stri
}
static const int INPUT_NUM_CHANNELS = 15;
+static const int INPUT_DENOISING_DEPTH = 0;
+static const int INPUT_DENOISING_NORMAL = 1;
+static const int INPUT_DENOISING_SHADOWING = 4;
+static const int INPUT_DENOISING_ALBEDO = 5;
+static const int INPUT_NOISY_IMAGE = 8;
+static const int INPUT_DENOISING_VARIANCE = 11;
+static const int INPUT_DENOISING_INTENSITY = 14;
static vector<ChannelMapping> input_channels()
{
vector<ChannelMapping> map;
- fill_mapping(map, 0, "Denoising Depth", "Z");
- fill_mapping(map, 1, "Denoising Normal", "XYZ");
- fill_mapping(map, 4, "Denoising Shadowing", "X");
- fill_mapping(map, 5, "Denoising Albedo", "RGB");
- fill_mapping(map, 8, "Noisy Image", "RGB");
- fill_mapping(map, 11, "Denoising Variance", "RGB");
- fill_mapping(map, 14, "Denoising Intensity", "X");
+ fill_mapping(map, INPUT_DENOISING_DEPTH, "Denoising Depth", "Z");
+ fill_mapping(map, INPUT_DENOISING_NORMAL, "Denoising Normal", "XYZ");
+ fill_mapping(map, INPUT_DENOISING_SHADOWING, "Denoising Shadowing", "X");
+ fill_mapping(map, INPUT_DENOISING_ALBEDO, "Denoising Albedo", "RGB");
+ fill_mapping(map, INPUT_NOISY_IMAGE, "Noisy Image", "RGB");
+ fill_mapping(map, INPUT_DENOISING_VARIANCE, "Denoising Variance", "RGB");
+ fill_mapping(map, INPUT_DENOISING_INTENSITY, "Denoising Intensity", "X");
return map;
}
@@ -261,6 +268,7 @@ bool DenoiseTask::acquire_tile(Device *device, Device *tile_device, RenderTile &
* a different buffer to avoid having to copy an entire horizontal slice of the image. */
void DenoiseTask::map_neighboring_tiles(RenderTile *tiles, Device *tile_device)
{
+ /* Fill tile information. */
for(int i = 0; i < 9; i++) {
if(i == 4) {
continue;
@@ -278,10 +286,30 @@ void DenoiseTask::map_neighboring_tiles(RenderTile *tiles, Device *tile_device)
tiles[i].stride = image.width;
}
+ /* Allocate output buffer. */
device_vector<float> *output_mem = new device_vector<float>(tile_device, "denoising_output", MEM_READ_WRITE);
output_mem->alloc(OUTPUT_NUM_CHANNELS*tiles[4].w*tiles[4].h);
- output_mem->zero_to_device();
+ /* Fill output buffer with noisy image, assumed by kernel_filter_finalize
+ * when skipping denoising of some pixels. */
+ float *result = output_mem->data();
+ float *in = &image.pixels[image.num_channels*(tiles[4].y*image.width + tiles[4].x)];
+
+ const DenoiseImageLayer& layer = image.layers[current_layer];
+ const int *input_to_image_channel = layer.input_to_image_channel.data();
+
+ for(int y = 0; y < tiles[4].h; y++) {
+ for(int x = 0; x < tiles[4].w; x++, result += OUTPUT_NUM_CHANNELS) {
+ for(int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
+ result[i] = in[image.num_channels*x + input_to_image_channel[INPUT_NOISY_IMAGE + i]];
+ }
+ }
+ in += image.num_channels * image.width;
+ }
+
+ output_mem->copy_to_device();
+
+ /* Fill output tile info. */
tiles[9] = tiles[4];
tiles[9].buffer = output_mem->device_pointer;
tiles[9].stride = tiles[9].w;
@@ -300,6 +328,7 @@ void DenoiseTask::unmap_neighboring_tiles(RenderTile *tiles)
output_pixels.erase(tiles[4].tile_index);
output_lock.unlock();
+ /* Copy denoised pixels from device. */
output_mem->copy_from_device(0, OUTPUT_NUM_CHANNELS*tiles[9].w, tiles[9].h);
float *result = output_mem->data();
@@ -317,6 +346,7 @@ void DenoiseTask::unmap_neighboring_tiles(RenderTile *tiles)
out += image.num_channels * image.width;
}
+ /* Free device buffer. */
output_mem->free();
delete output_mem;
}