1 /*
2 * Copyright 2011-2018 Blender Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "render/denoising.h"
18
19 #include "kernel/filter/filter_defines.h"
20
21 #include "util/util_foreach.h"
22 #include "util/util_map.h"
23 #include "util/util_system.h"
24 #include "util/util_task.h"
25 #include "util/util_time.h"
26
27 #include <OpenImageIO/filesystem.h>
28
29 CCL_NAMESPACE_BEGIN
30
31 /* Utility Functions */
32
print_progress(int num,int total,int frame,int num_frames)33 static void print_progress(int num, int total, int frame, int num_frames)
34 {
35 const char *label = "Denoise Frame ";
36 int cols = system_console_width();
37
38 cols -= strlen(label);
39
40 int len = 1;
41 for (int x = total; x > 9; x /= 10) {
42 len++;
43 }
44
45 int bars = cols - 2 * len - 6;
46
47 printf("\r%s", label);
48
49 if (num_frames > 1) {
50 int frame_len = 1;
51 for (int x = num_frames - 1; x > 9; x /= 10) {
52 frame_len++;
53 }
54 bars -= frame_len + 2;
55 printf("%*d ", frame_len, frame);
56 }
57
58 int v = int(float(num) * bars / total);
59 printf("[");
60 for (int i = 0; i < v; i++) {
61 printf("=");
62 }
63 if (v < bars) {
64 printf(">");
65 }
66 for (int i = v + 1; i < bars; i++) {
67 printf(" ");
68 }
69 printf(string_printf("] %%%dd / %d", len, total).c_str(), num);
70 fflush(stdout);
71 }
72
73 /* Splits in at its last dot, setting suffix to the part after the dot and in to the part before
74 * it. Returns whether a dot was found. */
split_last_dot(string & in,string & suffix)75 static bool split_last_dot(string &in, string &suffix)
76 {
77 size_t pos = in.rfind(".");
78 if (pos == string::npos) {
79 return false;
80 }
81 suffix = in.substr(pos + 1);
82 in = in.substr(0, pos);
83 return true;
84 }
85
86 /* Separate channel names as generated by Blender.
87 * If views is true:
88 * Inputs are expected in the form RenderLayer.Pass.View.Channel, sets renderlayer to
89 * "RenderLayer.View" Otherwise: Inputs are expected in the form RenderLayer.Pass.Channel */
parse_channel_name(string name,string & renderlayer,string & pass,string & channel,bool multiview_channels)90 static bool parse_channel_name(
91 string name, string &renderlayer, string &pass, string &channel, bool multiview_channels)
92 {
93 if (!split_last_dot(name, channel)) {
94 return false;
95 }
96 string view;
97 if (multiview_channels && !split_last_dot(name, view)) {
98 return false;
99 }
100 if (!split_last_dot(name, pass)) {
101 return false;
102 }
103 renderlayer = name;
104
105 if (multiview_channels) {
106 renderlayer += "." + view;
107 }
108
109 return true;
110 }
111
112 /* Channel Mapping */
113
114 struct ChannelMapping {
115 int channel;
116 string name;
117 };
118
fill_mapping(vector<ChannelMapping> & map,int pos,string name,string channels)119 static void fill_mapping(vector<ChannelMapping> &map, int pos, string name, string channels)
120 {
121 for (const char *chan = channels.c_str(); *chan; chan++) {
122 map.push_back({pos++, name + "." + *chan});
123 }
124 }
125
126 static const int INPUT_NUM_CHANNELS = 15;
127 static const int INPUT_DENOISING_DEPTH = 0;
128 static const int INPUT_DENOISING_NORMAL = 1;
129 static const int INPUT_DENOISING_SHADOWING = 4;
130 static const int INPUT_DENOISING_ALBEDO = 5;
131 static const int INPUT_NOISY_IMAGE = 8;
132 static const int INPUT_DENOISING_VARIANCE = 11;
133 static const int INPUT_DENOISING_INTENSITY = 14;
input_channels()134 static vector<ChannelMapping> input_channels()
135 {
136 vector<ChannelMapping> map;
137 fill_mapping(map, INPUT_DENOISING_DEPTH, "Denoising Depth", "Z");
138 fill_mapping(map, INPUT_DENOISING_NORMAL, "Denoising Normal", "XYZ");
139 fill_mapping(map, INPUT_DENOISING_SHADOWING, "Denoising Shadowing", "X");
140 fill_mapping(map, INPUT_DENOISING_ALBEDO, "Denoising Albedo", "RGB");
141 fill_mapping(map, INPUT_NOISY_IMAGE, "Noisy Image", "RGB");
142 fill_mapping(map, INPUT_DENOISING_VARIANCE, "Denoising Variance", "RGB");
143 fill_mapping(map, INPUT_DENOISING_INTENSITY, "Denoising Intensity", "X");
144 return map;
145 }
146
147 static const int OUTPUT_NUM_CHANNELS = 3;
output_channels()148 static vector<ChannelMapping> output_channels()
149 {
150 vector<ChannelMapping> map;
151 fill_mapping(map, 0, "Combined", "RGB");
152 return map;
153 }
154
155 /* Renderlayer Handling */
156
detect_denoising_channels()157 bool DenoiseImageLayer::detect_denoising_channels()
158 {
159 /* Map device input to image channels. */
160 input_to_image_channel.clear();
161 input_to_image_channel.resize(INPUT_NUM_CHANNELS, -1);
162
163 foreach (const ChannelMapping &mapping, input_channels()) {
164 vector<string>::iterator i = find(channels.begin(), channels.end(), mapping.name);
165 if (i == channels.end()) {
166 return false;
167 }
168
169 size_t input_channel = mapping.channel;
170 size_t layer_channel = i - channels.begin();
171 input_to_image_channel[input_channel] = layer_to_image_channel[layer_channel];
172 }
173
174 /* Map device output to image channels. */
175 output_to_image_channel.clear();
176 output_to_image_channel.resize(OUTPUT_NUM_CHANNELS, -1);
177
178 foreach (const ChannelMapping &mapping, output_channels()) {
179 vector<string>::iterator i = find(channels.begin(), channels.end(), mapping.name);
180 if (i == channels.end()) {
181 return false;
182 }
183
184 size_t output_channel = mapping.channel;
185 size_t layer_channel = i - channels.begin();
186 output_to_image_channel[output_channel] = layer_to_image_channel[layer_channel];
187 }
188
189 /* Check that all buffer channels are correctly set. */
190 for (int i = 0; i < INPUT_NUM_CHANNELS; i++) {
191 assert(input_to_image_channel[i] >= 0);
192 }
193 for (int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
194 assert(output_to_image_channel[i] >= 0);
195 }
196
197 return true;
198 }
199
match_channels(int neighbor,const std::vector<string> & channelnames,const std::vector<string> & neighbor_channelnames)200 bool DenoiseImageLayer::match_channels(int neighbor,
201 const std::vector<string> &channelnames,
202 const std::vector<string> &neighbor_channelnames)
203 {
204 neighbor_input_to_image_channel.resize(neighbor + 1);
205 vector<int> &mapping = neighbor_input_to_image_channel[neighbor];
206
207 assert(mapping.size() == 0);
208 mapping.resize(input_to_image_channel.size(), -1);
209
210 for (int i = 0; i < input_to_image_channel.size(); i++) {
211 const string &channel = channelnames[input_to_image_channel[i]];
212 std::vector<string>::const_iterator frame_channel = find(
213 neighbor_channelnames.begin(), neighbor_channelnames.end(), channel);
214
215 if (frame_channel == neighbor_channelnames.end()) {
216 return false;
217 }
218
219 mapping[i] = frame_channel - neighbor_channelnames.begin();
220 }
221
222 return true;
223 }
224
225 /* Denoise Task */
226
DenoiseTask(Device * device,Denoiser * denoiser,int frame,const vector<int> & neighbor_frames)227 DenoiseTask::DenoiseTask(Device *device,
228 Denoiser *denoiser,
229 int frame,
230 const vector<int> &neighbor_frames)
231 : denoiser(denoiser),
232 device(device),
233 frame(frame),
234 neighbor_frames(neighbor_frames),
235 current_layer(0),
236 input_pixels(device, "filter input buffer", MEM_READ_ONLY),
237 num_tiles(0)
238 {
239 image.samples = denoiser->samples_override;
240 }
241
~DenoiseTask()242 DenoiseTask::~DenoiseTask()
243 {
244 free();
245 }
246
247 /* Device callbacks */
248
acquire_tile(Device * device,Device * tile_device,RenderTile & tile)249 bool DenoiseTask::acquire_tile(Device *device, Device *tile_device, RenderTile &tile)
250 {
251 thread_scoped_lock tile_lock(tiles_mutex);
252
253 if (tiles.empty()) {
254 return false;
255 }
256
257 tile = tiles.front();
258 tiles.pop_front();
259
260 device->map_tile(tile_device, tile);
261
262 print_progress(num_tiles - tiles.size(), num_tiles, frame, denoiser->num_frames);
263
264 return true;
265 }
266
267 /* Mapping tiles is required for regular rendering since each tile has its separate memory
268 * which may be allocated on a different device.
269 * For standalone denoising, there is a single memory that is present on all devices, so the only
270 * thing that needs to be done here is to specify the surrounding tile geometry.
271 *
272 * However, since there is only one large memory, the denoised result has to be written to
273 * a different buffer to avoid having to copy an entire horizontal slice of the image. */
map_neighboring_tiles(RenderTileNeighbors & neighbors,Device * tile_device)274 void DenoiseTask::map_neighboring_tiles(RenderTileNeighbors &neighbors, Device *tile_device)
275 {
276 RenderTile ¢er_tile = neighbors.tiles[RenderTileNeighbors::CENTER];
277 RenderTile &target_tile = neighbors.target;
278
279 /* Fill tile information. */
280 for (int i = 0; i < RenderTileNeighbors::SIZE; i++) {
281 if (i == RenderTileNeighbors::CENTER) {
282 continue;
283 }
284
285 RenderTile &tile = neighbors.tiles[i];
286 int dx = (i % 3) - 1;
287 int dy = (i / 3) - 1;
288 tile.x = clamp(center_tile.x + dx * denoiser->tile_size.x, 0, image.width);
289 tile.w = clamp(center_tile.x + (dx + 1) * denoiser->tile_size.x, 0, image.width) - tile.x;
290 tile.y = clamp(center_tile.y + dy * denoiser->tile_size.y, 0, image.height);
291 tile.h = clamp(center_tile.y + (dy + 1) * denoiser->tile_size.y, 0, image.height) - tile.y;
292
293 tile.buffer = center_tile.buffer;
294 tile.offset = center_tile.offset;
295 tile.stride = image.width;
296 }
297
298 /* Allocate output buffer. */
299 device_vector<float> *output_mem = new device_vector<float>(
300 tile_device, "denoising_output", MEM_READ_WRITE);
301 output_mem->alloc(OUTPUT_NUM_CHANNELS * center_tile.w * center_tile.h);
302
303 /* Fill output buffer with noisy image, assumed by kernel_filter_finalize
304 * when skipping denoising of some pixels. */
305 float *result = output_mem->data();
306 float *in = &image.pixels[image.num_channels * (center_tile.y * image.width + center_tile.x)];
307
308 const DenoiseImageLayer &layer = image.layers[current_layer];
309 const int *input_to_image_channel = layer.input_to_image_channel.data();
310
311 for (int y = 0; y < center_tile.h; y++) {
312 for (int x = 0; x < center_tile.w; x++, result += OUTPUT_NUM_CHANNELS) {
313 for (int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
314 result[i] = in[image.num_channels * x + input_to_image_channel[INPUT_NOISY_IMAGE + i]];
315 }
316 }
317 in += image.num_channels * image.width;
318 }
319
320 output_mem->copy_to_device();
321
322 /* Fill output tile info. */
323 target_tile = center_tile;
324 target_tile.buffer = output_mem->device_pointer;
325 target_tile.stride = target_tile.w;
326 target_tile.offset -= target_tile.x + target_tile.y * target_tile.stride;
327
328 thread_scoped_lock output_lock(output_mutex);
329 assert(output_pixels.count(center_tile.tile_index) == 0);
330 output_pixels[target_tile.tile_index] = output_mem;
331 }
332
unmap_neighboring_tiles(RenderTileNeighbors & neighbors)333 void DenoiseTask::unmap_neighboring_tiles(RenderTileNeighbors &neighbors)
334 {
335 RenderTile ¢er_tile = neighbors.tiles[RenderTileNeighbors::CENTER];
336 RenderTile &target_tile = neighbors.target;
337
338 thread_scoped_lock output_lock(output_mutex);
339 assert(output_pixels.count(center_tile.tile_index) == 1);
340 device_vector<float> *output_mem = output_pixels[target_tile.tile_index];
341 output_pixels.erase(center_tile.tile_index);
342 output_lock.unlock();
343
344 /* Copy denoised pixels from device. */
345 output_mem->copy_from_device(0, OUTPUT_NUM_CHANNELS * target_tile.w, target_tile.h);
346
347 float *result = output_mem->data();
348 float *out = &image.pixels[image.num_channels * (target_tile.y * image.width + target_tile.x)];
349
350 const DenoiseImageLayer &layer = image.layers[current_layer];
351 const int *output_to_image_channel = layer.output_to_image_channel.data();
352
353 for (int y = 0; y < target_tile.h; y++) {
354 for (int x = 0; x < target_tile.w; x++, result += OUTPUT_NUM_CHANNELS) {
355 for (int i = 0; i < OUTPUT_NUM_CHANNELS; i++) {
356 out[image.num_channels * x + output_to_image_channel[i]] = result[i];
357 }
358 }
359 out += image.num_channels * image.width;
360 }
361
362 /* Free device buffer. */
363 output_mem->free();
364 delete output_mem;
365 }
366
release_tile()367 void DenoiseTask::release_tile()
368 {
369 }
370
get_cancel()371 bool DenoiseTask::get_cancel()
372 {
373 return false;
374 }
375
create_task(DeviceTask & task)376 void DenoiseTask::create_task(DeviceTask &task)
377 {
378 /* Callback functions. */
379 task.acquire_tile = function_bind(&DenoiseTask::acquire_tile, this, device, _1, _2);
380 task.map_neighbor_tiles = function_bind(&DenoiseTask::map_neighboring_tiles, this, _1, _2);
381 task.unmap_neighbor_tiles = function_bind(&DenoiseTask::unmap_neighboring_tiles, this, _1);
382 task.release_tile = function_bind(&DenoiseTask::release_tile, this);
383 task.get_cancel = function_bind(&DenoiseTask::get_cancel, this);
384
385 /* Denoising parameters. */
386 task.denoising = denoiser->params;
387 task.denoising.type = DENOISER_NLM;
388 task.denoising.use = true;
389 task.denoising.store_passes = false;
390 task.denoising_from_render = false;
391
392 task.denoising_frames.resize(neighbor_frames.size());
393 for (int i = 0; i < neighbor_frames.size(); i++) {
394 task.denoising_frames[i] = neighbor_frames[i] - frame;
395 }
396
397 /* Buffer parameters. */
398 task.pass_stride = INPUT_NUM_CHANNELS;
399 task.target_pass_stride = OUTPUT_NUM_CHANNELS;
400 task.pass_denoising_data = 0;
401 task.pass_denoising_clean = -1;
402 task.frame_stride = image.width * image.height * INPUT_NUM_CHANNELS;
403
404 /* Create tiles. */
405 thread_scoped_lock tile_lock(tiles_mutex);
406 thread_scoped_lock output_lock(output_mutex);
407
408 tiles.clear();
409 assert(output_pixels.empty());
410 output_pixels.clear();
411
412 int tiles_x = divide_up(image.width, denoiser->tile_size.x);
413 int tiles_y = divide_up(image.height, denoiser->tile_size.y);
414
415 for (int ty = 0; ty < tiles_y; ty++) {
416 for (int tx = 0; tx < tiles_x; tx++) {
417 RenderTile tile;
418 tile.x = tx * denoiser->tile_size.x;
419 tile.y = ty * denoiser->tile_size.y;
420 tile.w = min(image.width - tile.x, denoiser->tile_size.x);
421 tile.h = min(image.height - tile.y, denoiser->tile_size.y);
422 tile.start_sample = 0;
423 tile.num_samples = image.layers[current_layer].samples;
424 tile.sample = 0;
425 tile.offset = 0;
426 tile.stride = image.width;
427 tile.tile_index = ty * tiles_x + tx;
428 tile.task = RenderTile::DENOISE;
429 tile.buffers = NULL;
430 tile.buffer = input_pixels.device_pointer;
431 tiles.push_back(tile);
432 }
433 }
434
435 num_tiles = tiles.size();
436 }
437
438 /* Denoiser Operations */
439
load_input_pixels(int layer)440 bool DenoiseTask::load_input_pixels(int layer)
441 {
442 int w = image.width;
443 int h = image.height;
444 int num_pixels = image.width * image.height;
445 int frame_stride = num_pixels * INPUT_NUM_CHANNELS;
446
447 /* Load center image */
448 DenoiseImageLayer &image_layer = image.layers[layer];
449
450 float *buffer_data = input_pixels.data();
451 image.read_pixels(image_layer, buffer_data);
452 buffer_data += frame_stride;
453
454 /* Load neighbor images */
455 for (int i = 0; i < image.in_neighbors.size(); i++) {
456 if (!image.read_neighbor_pixels(i, image_layer, buffer_data)) {
457 error = "Failed to read neighbor frame pixels";
458 return false;
459 }
460 buffer_data += frame_stride;
461 }
462
463 /* Preprocess */
464 buffer_data = input_pixels.data();
465 for (int neighbor = 0; neighbor < image.in_neighbors.size() + 1; neighbor++) {
466 /* Clamp */
467 if (denoiser->params.clamp_input) {
468 for (int i = 0; i < num_pixels * INPUT_NUM_CHANNELS; i++) {
469 buffer_data[i] = clamp(buffer_data[i], -1e8f, 1e8f);
470 }
471 }
472
473 /* Box blur */
474 int r = 5 * denoiser->params.radius;
475 float *data = buffer_data + 14;
476 array<float> temp(num_pixels);
477
478 for (int y = 0; y < h; y++) {
479 for (int x = 0; x < w; x++) {
480 int n = 0;
481 float sum = 0.0f;
482 for (int dx = max(x - r, 0); dx < min(x + r + 1, w); dx++, n++) {
483 sum += data[INPUT_NUM_CHANNELS * (y * w + dx)];
484 }
485 temp[y * w + x] = sum / n;
486 }
487 }
488
489 for (int y = 0; y < h; y++) {
490 for (int x = 0; x < w; x++) {
491 int n = 0;
492 float sum = 0.0f;
493
494 for (int dy = max(y - r, 0); dy < min(y + r + 1, h); dy++, n++) {
495 sum += temp[dy * w + x];
496 }
497
498 data[INPUT_NUM_CHANNELS * (y * w + x)] = sum / n;
499 }
500 }
501
502 /* Highlight compression */
503 data = buffer_data + 8;
504 for (int y = 0; y < h; y++) {
505 for (int x = 0; x < w; x++) {
506 int idx = INPUT_NUM_CHANNELS * (y * w + x);
507 float3 color = make_float3(data[idx], data[idx + 1], data[idx + 2]);
508 color = color_highlight_compress(color, NULL);
509 data[idx] = color.x;
510 data[idx + 1] = color.y;
511 data[idx + 2] = color.z;
512 }
513 }
514
515 buffer_data += frame_stride;
516 }
517
518 /* Copy to device */
519 input_pixels.copy_to_device();
520
521 return true;
522 }
523
524 /* Task stages */
525
load()526 bool DenoiseTask::load()
527 {
528 string center_filepath = denoiser->input[frame];
529 if (!image.load(center_filepath, error)) {
530 return false;
531 }
532
533 if (!image.load_neighbors(denoiser->input, neighbor_frames, error)) {
534 return false;
535 }
536
537 if (image.layers.empty()) {
538 error = "No image layers found to denoise in " + center_filepath;
539 return false;
540 }
541
542 /* Allocate device buffer. */
543 int num_frames = image.in_neighbors.size() + 1;
544 input_pixels.alloc(image.width * INPUT_NUM_CHANNELS, image.height * num_frames);
545 input_pixels.zero_to_device();
546
547 /* Read pixels for first layer. */
548 current_layer = 0;
549 if (!load_input_pixels(current_layer)) {
550 return false;
551 }
552
553 return true;
554 }
555
exec()556 bool DenoiseTask::exec()
557 {
558 for (current_layer = 0; current_layer < image.layers.size(); current_layer++) {
559 /* Read pixels for secondary layers, first was already loaded. */
560 if (current_layer > 0) {
561 if (!load_input_pixels(current_layer)) {
562 return false;
563 }
564 }
565
566 /* Run task on device. */
567 DeviceTask task(DeviceTask::RENDER);
568 create_task(task);
569 device->task_add(task);
570 device->task_wait();
571
572 printf("\n");
573 }
574
575 return true;
576 }
577
save()578 bool DenoiseTask::save()
579 {
580 bool ok = image.save_output(denoiser->output[frame], error);
581 free();
582 return ok;
583 }
584
free()585 void DenoiseTask::free()
586 {
587 image.free();
588 input_pixels.free();
589 assert(output_pixels.empty());
590 }
591
592 /* Denoise Image Storage */
593
DenoiseImage()594 DenoiseImage::DenoiseImage()
595 {
596 width = 0;
597 height = 0;
598 num_channels = 0;
599 samples = 0;
600 }
601
~DenoiseImage()602 DenoiseImage::~DenoiseImage()
603 {
604 free();
605 }
606
close_input()607 void DenoiseImage::close_input()
608 {
609 in_neighbors.clear();
610 }
611
free()612 void DenoiseImage::free()
613 {
614 close_input();
615 pixels.clear();
616 }
617
parse_channels(const ImageSpec & in_spec,string & error)618 bool DenoiseImage::parse_channels(const ImageSpec &in_spec, string &error)
619 {
620 const std::vector<string> &channels = in_spec.channelnames;
621 const ParamValue *multiview = in_spec.find_attribute("multiView");
622 const bool multiview_channels = (multiview && multiview->type().basetype == TypeDesc::STRING &&
623 multiview->type().arraylen >= 2);
624
625 layers.clear();
626
627 /* Loop over all the channels in the file, parse their name and sort them
628 * by RenderLayer.
629 * Channels that can't be parsed are directly passed through to the output. */
630 map<string, DenoiseImageLayer> file_layers;
631 for (int i = 0; i < channels.size(); i++) {
632 string layer, pass, channel;
633 if (parse_channel_name(channels[i], layer, pass, channel, multiview_channels)) {
634 file_layers[layer].channels.push_back(pass + "." + channel);
635 file_layers[layer].layer_to_image_channel.push_back(i);
636 }
637 }
638
639 /* Loop over all detected RenderLayers, check whether they contain a full set of input channels.
640 * Any channels that won't be processed internally are also passed through. */
641 for (map<string, DenoiseImageLayer>::iterator i = file_layers.begin(); i != file_layers.end();
642 ++i) {
643 const string &name = i->first;
644 DenoiseImageLayer &layer = i->second;
645
646 /* Check for full pass set. */
647 if (!layer.detect_denoising_channels()) {
648 continue;
649 }
650
651 layer.name = name;
652 layer.samples = samples;
653
654 /* If the sample value isn't set yet, check if there is a layer-specific one in the input file.
655 */
656 if (layer.samples < 1) {
657 string sample_string = in_spec.get_string_attribute("cycles." + name + ".samples", "");
658 if (sample_string != "") {
659 if (!sscanf(sample_string.c_str(), "%d", &layer.samples)) {
660 error = "Failed to parse samples metadata: " + sample_string;
661 return false;
662 }
663 }
664 }
665
666 if (layer.samples < 1) {
667 error = string_printf(
668 "No sample number specified in the file for layer %s or on the command line",
669 name.c_str());
670 return false;
671 }
672
673 layers.push_back(layer);
674 }
675
676 return true;
677 }
678
read_pixels(const DenoiseImageLayer & layer,float * input_pixels)679 void DenoiseImage::read_pixels(const DenoiseImageLayer &layer, float *input_pixels)
680 {
681 /* Pixels from center file have already been loaded into pixels.
682 * We copy a subset into the device input buffer with channels reshuffled. */
683 const int *input_to_image_channel = layer.input_to_image_channel.data();
684
685 for (int i = 0; i < width * height; i++) {
686 for (int j = 0; j < INPUT_NUM_CHANNELS; j++) {
687 int image_channel = input_to_image_channel[j];
688 input_pixels[i * INPUT_NUM_CHANNELS + j] =
689 pixels[((size_t)i) * num_channels + image_channel];
690 }
691 }
692 }
693
read_neighbor_pixels(int neighbor,const DenoiseImageLayer & layer,float * input_pixels)694 bool DenoiseImage::read_neighbor_pixels(int neighbor,
695 const DenoiseImageLayer &layer,
696 float *input_pixels)
697 {
698 /* Load pixels from neighboring frames, and copy them into device buffer
699 * with channels reshuffled. */
700 size_t num_pixels = (size_t)width * (size_t)height;
701 array<float> neighbor_pixels(num_pixels * num_channels);
702 if (!in_neighbors[neighbor]->read_image(TypeDesc::FLOAT, neighbor_pixels.data())) {
703 return false;
704 }
705
706 const int *input_to_image_channel = layer.neighbor_input_to_image_channel[neighbor].data();
707
708 for (int i = 0; i < width * height; i++) {
709 for (int j = 0; j < INPUT_NUM_CHANNELS; j++) {
710 int image_channel = input_to_image_channel[j];
711 input_pixels[i * INPUT_NUM_CHANNELS + j] =
712 neighbor_pixels[((size_t)i) * num_channels + image_channel];
713 }
714 }
715
716 return true;
717 }
718
load(const string & in_filepath,string & error)719 bool DenoiseImage::load(const string &in_filepath, string &error)
720 {
721 if (!Filesystem::is_regular(in_filepath)) {
722 error = "Couldn't find file: " + in_filepath;
723 return false;
724 }
725
726 unique_ptr<ImageInput> in(ImageInput::open(in_filepath));
727 if (!in) {
728 error = "Couldn't open file: " + in_filepath;
729 return false;
730 }
731
732 in_spec = in->spec();
733 width = in_spec.width;
734 height = in_spec.height;
735 num_channels = in_spec.nchannels;
736
737 if (!parse_channels(in_spec, error)) {
738 return false;
739 }
740
741 if (layers.size() == 0) {
742 error = "Could not find a render layer containing denoising info";
743 return false;
744 }
745
746 size_t num_pixels = (size_t)width * (size_t)height;
747 pixels.resize(num_pixels * num_channels);
748
749 /* Read all channels into buffer. Reading all channels at once is faster
750 * than individually due to interleaved EXR channel storage. */
751 if (!in->read_image(TypeDesc::FLOAT, pixels.data())) {
752 error = "Failed to read image: " + in_filepath;
753 return false;
754 }
755
756 return true;
757 }
758
load_neighbors(const vector<string> & filepaths,const vector<int> & frames,string & error)759 bool DenoiseImage::load_neighbors(const vector<string> &filepaths,
760 const vector<int> &frames,
761 string &error)
762 {
763 if (frames.size() > DENOISE_MAX_FRAMES - 1) {
764 error = string_printf("Maximum number of neighbors (%d) exceeded\n", DENOISE_MAX_FRAMES - 1);
765 return false;
766 }
767
768 for (int neighbor = 0; neighbor < frames.size(); neighbor++) {
769 int frame = frames[neighbor];
770 const string &filepath = filepaths[frame];
771
772 if (!Filesystem::is_regular(filepath)) {
773 error = "Couldn't find neighbor frame: " + filepath;
774 return false;
775 }
776
777 unique_ptr<ImageInput> in_neighbor(ImageInput::open(filepath));
778 if (!in_neighbor) {
779 error = "Couldn't open neighbor frame: " + filepath;
780 return false;
781 }
782
783 const ImageSpec &neighbor_spec = in_neighbor->spec();
784 if (neighbor_spec.width != width || neighbor_spec.height != height) {
785 error = "Neighbor frame has different dimensions: " + filepath;
786 return false;
787 }
788
789 foreach (DenoiseImageLayer &layer, layers) {
790 if (!layer.match_channels(neighbor, in_spec.channelnames, neighbor_spec.channelnames)) {
791 error = "Neighbor frame misses denoising data passes: " + filepath;
792 return false;
793 }
794 }
795
796 in_neighbors.push_back(std::move(in_neighbor));
797 }
798
799 return true;
800 }
801
save_output(const string & out_filepath,string & error)802 bool DenoiseImage::save_output(const string &out_filepath, string &error)
803 {
804 /* Save image with identical dimensions, channels and metadata. */
805 ImageSpec out_spec = in_spec;
806
807 /* Ensure that the output frame contains sample information even if the input didn't. */
808 for (int i = 0; i < layers.size(); i++) {
809 string name = "cycles." + layers[i].name + ".samples";
810 if (!out_spec.find_attribute(name, TypeDesc::STRING)) {
811 out_spec.attribute(name, TypeDesc::STRING, string_printf("%d", layers[i].samples));
812 }
813 }
814
815 /* We don't need input anymore at this point, and will possibly
816 * overwrite the same file. */
817 close_input();
818
819 /* Write to temporary file path, so we denoise images in place and don't
820 * risk destroying files when something goes wrong in file saving. */
821 string extension = OIIO::Filesystem::extension(out_filepath);
822 string unique_name = ".denoise-tmp-" + OIIO::Filesystem::unique_path();
823 string tmp_filepath = out_filepath + unique_name + extension;
824 unique_ptr<ImageOutput> out(ImageOutput::create(tmp_filepath));
825
826 if (!out) {
827 error = "Failed to open temporary file " + tmp_filepath + " for writing";
828 return false;
829 }
830
831 /* Open temporary file and write image buffers. */
832 if (!out->open(tmp_filepath, out_spec)) {
833 error = "Failed to open file " + tmp_filepath + " for writing: " + out->geterror();
834 return false;
835 }
836
837 bool ok = true;
838 if (!out->write_image(TypeDesc::FLOAT, pixels.data())) {
839 error = "Failed to write to file " + tmp_filepath + ": " + out->geterror();
840 ok = false;
841 }
842
843 if (!out->close()) {
844 error = "Failed to save to file " + tmp_filepath + ": " + out->geterror();
845 ok = false;
846 }
847
848 out.reset();
849
850 /* Copy temporary file to outputput filepath. */
851 string rename_error;
852 if (ok && !OIIO::Filesystem::rename(tmp_filepath, out_filepath, rename_error)) {
853 error = "Failed to move denoised image to " + out_filepath + ": " + rename_error;
854 ok = false;
855 }
856
857 if (!ok) {
858 OIIO::Filesystem::remove(tmp_filepath);
859 }
860
861 return ok;
862 }
863
864 /* File pattern handling and outer loop over frames */
865
Denoiser(DeviceInfo & device_info)866 Denoiser::Denoiser(DeviceInfo &device_info)
867 {
868 samples_override = 0;
869 tile_size = make_int2(64, 64);
870
871 num_frames = 0;
872
873 /* Initialize task scheduler. */
874 TaskScheduler::init();
875
876 /* Initialize device. */
877 device = Device::create(device_info, stats, profiler, true);
878
879 DeviceRequestedFeatures req;
880 req.use_denoising = true;
881 device->load_kernels(req);
882 }
883
~Denoiser()884 Denoiser::~Denoiser()
885 {
886 delete device;
887 TaskScheduler::exit();
888 }
889
run()890 bool Denoiser::run()
891 {
892 assert(input.size() == output.size());
893
894 num_frames = output.size();
895
896 for (int frame = 0; frame < num_frames; frame++) {
897 /* Skip empty output paths. */
898 if (output[frame].empty()) {
899 continue;
900 }
901
902 /* Determine neighbor frame numbers that should be used for filtering. */
903 vector<int> neighbor_frames;
904 for (int f = frame - params.neighbor_frames; f <= frame + params.neighbor_frames; f++) {
905 if (f >= 0 && f < num_frames && f != frame) {
906 neighbor_frames.push_back(f);
907 }
908 }
909
910 /* Execute task. */
911 DenoiseTask task(device, this, frame, neighbor_frames);
912 if (!task.load()) {
913 error = task.error;
914 return false;
915 }
916
917 if (!task.exec()) {
918 error = task.error;
919 return false;
920 }
921
922 if (!task.save()) {
923 error = task.error;
924 return false;
925 }
926
927 task.free();
928 }
929
930 return true;
931 }
932
933 CCL_NAMESPACE_END
934