Blender  V3.3
film.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #include "scene/film.h"
5 #include "device/device.h"
6 #include "scene/background.h"
7 #include "scene/bake.h"
8 #include "scene/camera.h"
9 #include "scene/integrator.h"
10 #include "scene/mesh.h"
11 #include "scene/object.h"
12 #include "scene/scene.h"
13 #include "scene/stats.h"
14 #include "scene/tables.h"
15 
16 #include "util/algorithm.h"
17 #include "util/foreach.h"
18 #include "util/math.h"
19 #include "util/math_cdf.h"
20 #include "util/time.h"
21 
23 
24 /* Pixel Filter */
25 
26 static float filter_func_box(float /*v*/, float /*width*/)
27 {
28  return 1.0f;
29 }
30 
31 static float filter_func_gaussian(float v, float width)
32 {
33  v *= 6.0f / width;
34  return expf(-2.0f * v * v);
35 }
36 
37 static float filter_func_blackman_harris(float v, float width)
38 {
39  v = M_2PI_F * (v / width + 0.5f);
40  return 0.35875f - 0.48829f * cosf(v) + 0.14128f * cosf(2.0f * v) - 0.01168f * cosf(3.0f * v);
41 }
42 
44 {
46  float (*filter_func)(float, float) = NULL;
47 
48  switch (type) {
49  case FILTER_BOX:
50  filter_func = filter_func_box;
51  break;
52  case FILTER_GAUSSIAN:
53  filter_func = filter_func_gaussian;
54  width *= 3.0f;
55  break;
57  filter_func = filter_func_blackman_harris;
58  width *= 2.0f;
59  break;
60  default:
61  assert(0);
62  }
63 
64  /* Create importance sampling table. */
65 
66  /* TODO(sergey): With the even filter table size resolution we can not
67  * really make it nice symmetric importance map without sampling full range
68  * (meaning, we would need to sample full filter range and not use the
69  * make_symmetric argument).
70  *
71  * Current code matches exactly initial filter table code, but we should
72  * consider either making FILTER_TABLE_SIZE odd value or sample full filter.
73  */
74 
76  0.0f,
77  width * 0.5f,
78  function_bind(filter_func, _1, width),
79  true,
80  filter_table);
81 
82  return filter_table;
83 }
84 
85 /* Film */
86 
88 {
89  NodeType *type = NodeType::add("film", create);
90 
91  SOCKET_FLOAT(exposure, "Exposure", 0.8f);
92  SOCKET_FLOAT(pass_alpha_threshold, "Pass Alpha Threshold", 0.0f);
93 
94  static NodeEnum filter_enum;
95  filter_enum.insert("box", FILTER_BOX);
96  filter_enum.insert("gaussian", FILTER_GAUSSIAN);
97  filter_enum.insert("blackman_harris", FILTER_BLACKMAN_HARRIS);
98 
99  SOCKET_ENUM(filter_type, "Filter Type", filter_enum, FILTER_BOX);
100  SOCKET_FLOAT(filter_width, "Filter Width", 1.0f);
101 
102  SOCKET_FLOAT(mist_start, "Mist Start", 0.0f);
103  SOCKET_FLOAT(mist_depth, "Mist Depth", 100.0f);
104  SOCKET_FLOAT(mist_falloff, "Mist Falloff", 1.0f);
105 
106  const NodeEnum *pass_type_enum = Pass::get_type_enum();
107  SOCKET_ENUM(display_pass, "Display Pass", *pass_type_enum, PASS_COMBINED);
108 
109  SOCKET_BOOLEAN(show_active_pixels, "Show Active Pixels", false);
110 
111  static NodeEnum cryptomatte_passes_enum;
112  cryptomatte_passes_enum.insert("none", CRYPT_NONE);
113  cryptomatte_passes_enum.insert("object", CRYPT_OBJECT);
114  cryptomatte_passes_enum.insert("material", CRYPT_MATERIAL);
115  cryptomatte_passes_enum.insert("asset", CRYPT_ASSET);
116  cryptomatte_passes_enum.insert("accurate", CRYPT_ACCURATE);
117  SOCKET_ENUM(cryptomatte_passes, "Cryptomatte Passes", cryptomatte_passes_enum, CRYPT_NONE);
118 
119  SOCKET_INT(cryptomatte_depth, "Cryptomatte Depth", 0);
120 
121  SOCKET_BOOLEAN(use_approximate_shadow_catcher, "Use Approximate Shadow Catcher", false);
122 
123  return type;
124 }
125 
126 Film::Film() : Node(get_node_type()), filter_table_offset_(TABLE_OFFSET_INVALID)
127 {
128 }
129 
131 {
132 }
133 
135 {
136  Pass *pass = scene->create_node<Pass>();
137  pass->set_type(PASS_COMBINED);
138 }
139 
141 {
142  if (!is_modified())
143  return;
144 
145  scoped_callback_timer timer([scene](double time) {
146  if (scene->update_stats) {
147  scene->update_stats->film.times.add_entry({"update", time});
148  }
149  });
150 
151  device_free(device, dscene, scene);
152 
153  KernelFilm *kfilm = &dscene->data.film;
154 
155  /* update data */
156  kfilm->exposure = exposure;
157  kfilm->pass_alpha_threshold = pass_alpha_threshold;
158  kfilm->pass_flag = 0;
159 
160  kfilm->use_approximate_shadow_catcher = get_use_approximate_shadow_catcher();
161 
162  kfilm->light_pass_flag = 0;
163  kfilm->pass_stride = 0;
164 
165  /* Mark with PASS_UNUSED to avoid mask test in the kernel. */
166  kfilm->pass_combined = PASS_UNUSED;
167  kfilm->pass_depth = PASS_UNUSED;
168  kfilm->pass_position = PASS_UNUSED;
169  kfilm->pass_normal = PASS_UNUSED;
170  kfilm->pass_roughness = PASS_UNUSED;
171  kfilm->pass_motion = PASS_UNUSED;
172  kfilm->pass_motion_weight = PASS_UNUSED;
173  kfilm->pass_uv = PASS_UNUSED;
174  kfilm->pass_object_id = PASS_UNUSED;
175  kfilm->pass_material_id = PASS_UNUSED;
176  kfilm->pass_diffuse_color = PASS_UNUSED;
177  kfilm->pass_glossy_color = PASS_UNUSED;
178  kfilm->pass_transmission_color = PASS_UNUSED;
179  kfilm->pass_background = PASS_UNUSED;
180  kfilm->pass_emission = PASS_UNUSED;
181  kfilm->pass_ao = PASS_UNUSED;
182  kfilm->pass_diffuse_direct = PASS_UNUSED;
183  kfilm->pass_diffuse_indirect = PASS_UNUSED;
184  kfilm->pass_glossy_direct = PASS_UNUSED;
185  kfilm->pass_glossy_indirect = PASS_UNUSED;
186  kfilm->pass_transmission_direct = PASS_UNUSED;
187  kfilm->pass_transmission_indirect = PASS_UNUSED;
188  kfilm->pass_volume_direct = PASS_UNUSED;
189  kfilm->pass_volume_indirect = PASS_UNUSED;
190  kfilm->pass_shadow = PASS_UNUSED;
191  kfilm->pass_lightgroup = PASS_UNUSED;
192 
193  /* Mark passes as unused so that the kernel knows the pass is inaccessible. */
194  kfilm->pass_denoising_normal = PASS_UNUSED;
195  kfilm->pass_denoising_albedo = PASS_UNUSED;
196  kfilm->pass_denoising_depth = PASS_UNUSED;
197  kfilm->pass_sample_count = PASS_UNUSED;
198  kfilm->pass_adaptive_aux_buffer = PASS_UNUSED;
199  kfilm->pass_shadow_catcher = PASS_UNUSED;
200  kfilm->pass_shadow_catcher_sample_count = PASS_UNUSED;
201  kfilm->pass_shadow_catcher_matte = PASS_UNUSED;
202 
203  bool have_cryptomatte = false;
204  bool have_aov_color = false;
205  bool have_aov_value = false;
206  bool have_lightgroup = false;
207 
208  for (size_t i = 0; i < scene->passes.size(); i++) {
209  const Pass *pass = scene->passes[i];
210 
211  if (pass->get_type() == PASS_NONE || !pass->is_written()) {
212  continue;
213  }
214 
215  if (pass->get_mode() == PassMode::DENOISED) {
216  /* Generally we only storing offsets of the noisy passes. The display pass is an exception
217  * since it is a read operation and not a write. */
218  kfilm->pass_stride += pass->get_info().num_components;
219  continue;
220  }
221 
222  /* Can't do motion pass if no motion vectors are available. */
223  if (pass->get_type() == PASS_MOTION || pass->get_type() == PASS_MOTION_WEIGHT) {
225  kfilm->pass_stride += pass->get_info().num_components;
226  continue;
227  }
228  }
229 
230  const int pass_flag = (1 << (pass->get_type() % 32));
231  if (pass->get_type() <= PASS_CATEGORY_LIGHT_END) {
232  kfilm->light_pass_flag |= pass_flag;
233  }
234  else if (pass->get_type() <= PASS_CATEGORY_DATA_END) {
235  kfilm->pass_flag |= pass_flag;
236  }
237  else {
238  assert(pass->get_type() <= PASS_CATEGORY_BAKE_END);
239  }
240 
241  if (pass->get_lightgroup() != ustring()) {
242  if (!have_lightgroup) {
243  kfilm->pass_lightgroup = kfilm->pass_stride;
244  have_lightgroup = true;
245  }
246  kfilm->pass_stride += pass->get_info().num_components;
247  continue;
248  }
249 
250  switch (pass->get_type()) {
251  case PASS_COMBINED:
252  kfilm->pass_combined = kfilm->pass_stride;
253  break;
254  case PASS_DEPTH:
255  kfilm->pass_depth = kfilm->pass_stride;
256  break;
257  case PASS_NORMAL:
258  kfilm->pass_normal = kfilm->pass_stride;
259  break;
260  case PASS_POSITION:
261  kfilm->pass_position = kfilm->pass_stride;
262  break;
263  case PASS_ROUGHNESS:
264  kfilm->pass_roughness = kfilm->pass_stride;
265  break;
266  case PASS_UV:
267  kfilm->pass_uv = kfilm->pass_stride;
268  break;
269  case PASS_MOTION:
270  kfilm->pass_motion = kfilm->pass_stride;
271  break;
272  case PASS_MOTION_WEIGHT:
273  kfilm->pass_motion_weight = kfilm->pass_stride;
274  break;
275  case PASS_OBJECT_ID:
276  kfilm->pass_object_id = kfilm->pass_stride;
277  break;
278  case PASS_MATERIAL_ID:
279  kfilm->pass_material_id = kfilm->pass_stride;
280  break;
281 
282  case PASS_MIST:
283  kfilm->pass_mist = kfilm->pass_stride;
284  break;
285  case PASS_EMISSION:
286  kfilm->pass_emission = kfilm->pass_stride;
287  break;
288  case PASS_BACKGROUND:
289  kfilm->pass_background = kfilm->pass_stride;
290  break;
291  case PASS_AO:
292  kfilm->pass_ao = kfilm->pass_stride;
293  break;
294  case PASS_SHADOW:
295  kfilm->pass_shadow = kfilm->pass_stride;
296  break;
297 
298  case PASS_DIFFUSE_COLOR:
299  kfilm->pass_diffuse_color = kfilm->pass_stride;
300  break;
301  case PASS_GLOSSY_COLOR:
302  kfilm->pass_glossy_color = kfilm->pass_stride;
303  break;
305  kfilm->pass_transmission_color = kfilm->pass_stride;
306  break;
308  kfilm->pass_diffuse_indirect = kfilm->pass_stride;
309  break;
311  kfilm->pass_glossy_indirect = kfilm->pass_stride;
312  break;
314  kfilm->pass_transmission_indirect = kfilm->pass_stride;
315  break;
317  kfilm->pass_volume_indirect = kfilm->pass_stride;
318  break;
319  case PASS_DIFFUSE_DIRECT:
320  kfilm->pass_diffuse_direct = kfilm->pass_stride;
321  break;
322  case PASS_GLOSSY_DIRECT:
323  kfilm->pass_glossy_direct = kfilm->pass_stride;
324  break;
326  kfilm->pass_transmission_direct = kfilm->pass_stride;
327  break;
328  case PASS_VOLUME_DIRECT:
329  kfilm->pass_volume_direct = kfilm->pass_stride;
330  break;
331 
332  case PASS_BAKE_PRIMITIVE:
333  kfilm->pass_bake_primitive = kfilm->pass_stride;
334  break;
336  kfilm->pass_bake_differential = kfilm->pass_stride;
337  break;
338 
339  case PASS_CRYPTOMATTE:
340  kfilm->pass_cryptomatte = have_cryptomatte ?
341  min(kfilm->pass_cryptomatte, kfilm->pass_stride) :
342  kfilm->pass_stride;
343  have_cryptomatte = true;
344  break;
345 
347  kfilm->pass_denoising_normal = kfilm->pass_stride;
348  break;
350  kfilm->pass_denoising_albedo = kfilm->pass_stride;
351  break;
353  kfilm->pass_denoising_depth = kfilm->pass_stride;
354  break;
355 
356  case PASS_SHADOW_CATCHER:
357  kfilm->pass_shadow_catcher = kfilm->pass_stride;
358  break;
360  kfilm->pass_shadow_catcher_sample_count = kfilm->pass_stride;
361  break;
363  kfilm->pass_shadow_catcher_matte = kfilm->pass_stride;
364  break;
365 
367  kfilm->pass_adaptive_aux_buffer = kfilm->pass_stride;
368  break;
369  case PASS_SAMPLE_COUNT:
370  kfilm->pass_sample_count = kfilm->pass_stride;
371  break;
372 
373  case PASS_AOV_COLOR:
374  if (!have_aov_color) {
375  kfilm->pass_aov_color = kfilm->pass_stride;
376  have_aov_color = true;
377  }
378  break;
379  case PASS_AOV_VALUE:
380  if (!have_aov_value) {
381  kfilm->pass_aov_value = kfilm->pass_stride;
382  have_aov_value = true;
383  }
384  break;
385  default:
386  assert(false);
387  break;
388  }
389 
390  kfilm->pass_stride += pass->get_info().num_components;
391  }
392 
393  /* update filter table */
394  vector<float> table = filter_table(filter_type, filter_width);
395  scene->lookup_tables->remove_table(&filter_table_offset_);
396  filter_table_offset_ = scene->lookup_tables->add_table(dscene, table);
397  dscene->data.tables.filter_table_offset = (int)filter_table_offset_;
398 
399  /* mist pass parameters */
400  kfilm->mist_start = mist_start;
401  kfilm->mist_inv_depth = (mist_depth > 0.0f) ? 1.0f / mist_depth : 0.0f;
402  kfilm->mist_falloff = mist_falloff;
403 
404  kfilm->cryptomatte_passes = cryptomatte_passes;
405  kfilm->cryptomatte_depth = cryptomatte_depth;
406 
407  clear_modified();
408 }
409 
410 void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *scene)
411 {
412  scene->lookup_tables->remove_table(&filter_table_offset_);
413 }
414 
415 int Film::get_aov_offset(Scene *scene, string name, bool &is_color)
416 {
417  int offset_color = 0, offset_value = 0;
418  foreach (const Pass *pass, scene->passes) {
419  if (pass->get_name() == name) {
420  if (pass->get_type() == PASS_AOV_VALUE) {
421  is_color = false;
422  return offset_value;
423  }
424  else if (pass->get_type() == PASS_AOV_COLOR) {
425  is_color = true;
426  return offset_color;
427  }
428  }
429 
430  if (pass->get_type() == PASS_AOV_VALUE) {
431  offset_value += pass->get_info().num_components;
432  }
433  else if (pass->get_type() == PASS_AOV_COLOR) {
434  offset_color += pass->get_info().num_components;
435  }
436  }
437 
438  return -1;
439 }
440 
442 {
443  map<ustring, int> lightgroups;
444  int i = 0;
445  foreach (const Pass *pass, scene->passes) {
446  ustring lightgroup = pass->get_lightgroup();
447  if (!lightgroup.empty()) {
448  if (!lightgroups.count(lightgroup)) {
449  lightgroups[lightgroup] = i++;
450  }
451  }
452  }
453  if (scene->lightgroups != lightgroups) {
454  scene->lightgroups = lightgroups;
455  return true;
456  }
457 
458  return false;
459 }
460 
461 void Film::update_passes(Scene *scene, bool add_sample_count_pass)
462 {
463  const Background *background = scene->background;
464  const BakeManager *bake_manager = scene->bake_manager;
465  const ObjectManager *object_manager = scene->object_manager;
466  Integrator *integrator = scene->integrator;
467 
468  if (!is_modified() && !object_manager->need_update() && !integrator->is_modified() &&
469  !background->is_modified()) {
470  return;
471  }
472 
473  /* Remove auto generated passes and recreate them. */
474  remove_auto_passes(scene);
475 
476  /* Display pass for viewport. */
477  const PassType display_pass = get_display_pass();
478  add_auto_pass(scene, display_pass);
479 
480  /* Assumption is that a combined pass always exists for now, for example
481  * adaptive sampling is always based on a combined pass. But we should
482  * try to lift this limitation in the future for faster rendering of
483  * individual passes. */
484  if (display_pass != PASS_COMBINED) {
485  add_auto_pass(scene, PASS_COMBINED);
486  }
487 
488  /* Create passes needed for adaptive sampling. */
489  const AdaptiveSampling adaptive_sampling = integrator->get_adaptive_sampling();
490  if (adaptive_sampling.use) {
491  add_auto_pass(scene, PASS_SAMPLE_COUNT);
492  add_auto_pass(scene, PASS_ADAPTIVE_AUX_BUFFER);
493  }
494 
495  /* Create passes needed for denoising. */
496  const bool use_denoise = integrator->get_use_denoise();
497  if (use_denoise) {
498  if (integrator->get_use_denoise_pass_normal()) {
499  add_auto_pass(scene, PASS_DENOISING_NORMAL);
500  }
501  if (integrator->get_use_denoise_pass_albedo()) {
502  add_auto_pass(scene, PASS_DENOISING_ALBEDO);
503  }
504  }
505 
506  /* Create passes for shadow catcher. */
507  if (scene->has_shadow_catcher()) {
508  const bool need_background = get_use_approximate_shadow_catcher() &&
509  !background->get_transparent();
510 
511  add_auto_pass(scene, PASS_SHADOW_CATCHER);
512  add_auto_pass(scene, PASS_SHADOW_CATCHER_SAMPLE_COUNT);
513  add_auto_pass(scene, PASS_SHADOW_CATCHER_MATTE);
514 
515  if (need_background) {
516  add_auto_pass(scene, PASS_BACKGROUND);
517  }
518  }
520  add_auto_pass(scene, PASS_SHADOW_CATCHER);
521  add_auto_pass(scene, PASS_SHADOW_CATCHER_SAMPLE_COUNT);
522  }
523 
524  const vector<Pass *> passes_immutable = scene->passes;
525  for (const Pass *pass : passes_immutable) {
526  const PassInfo info = pass->get_info();
527  /* Add utility passes needed to generate some light passes. */
528  if (info.divide_type != PASS_NONE) {
529  add_auto_pass(scene, info.divide_type);
530  }
531  if (info.direct_type != PASS_NONE) {
532  add_auto_pass(scene, info.direct_type);
533  }
534  if (info.indirect_type != PASS_NONE) {
535  add_auto_pass(scene, info.indirect_type);
536  }
537 
538  /* NOTE: Enable all denoised passes when storage is requested.
539  * This way it is possible to tweak denoiser parameters later on. */
540  if (info.support_denoise && use_denoise) {
541  add_auto_pass(scene, pass->get_type(), PassMode::DENOISED);
542  }
543  }
544 
545  if (bake_manager->get_baking()) {
546  add_auto_pass(scene, PASS_BAKE_PRIMITIVE, "BakePrimitive");
547  add_auto_pass(scene, PASS_BAKE_DIFFERENTIAL, "BakeDifferential");
548  }
549 
550  if (add_sample_count_pass) {
552  add_auto_pass(scene, PASS_SAMPLE_COUNT);
553  }
554  }
555 
556  /* Remove duplicates and initialize internal pass info. */
557  finalize_passes(scene, use_denoise);
558 
559  /* Flush scene updates. */
560  const bool have_uv_pass = Pass::contains(scene->passes, PASS_UV);
561  const bool have_motion_pass = Pass::contains(scene->passes, PASS_MOTION);
562  const bool have_ao_pass = Pass::contains(scene->passes, PASS_AO);
563 
564  if (have_uv_pass != prev_have_uv_pass) {
566  foreach (Shader *shader, scene->shaders)
567  shader->need_update_uvs = true;
568  }
569  if (have_motion_pass != prev_have_motion_pass) {
571  }
572  if (have_ao_pass != prev_have_ao_pass) {
574  }
575 
576  prev_have_uv_pass = have_uv_pass;
577  prev_have_motion_pass = have_motion_pass;
578  prev_have_ao_pass = have_ao_pass;
579 
580  tag_modified();
581 
582  /* Debug logging. */
583  if (VLOG_INFO_IS_ON) {
584  VLOG_INFO << "Effective scene passes:";
585  for (const Pass *pass : scene->passes) {
586  VLOG_INFO << "- " << *pass;
587  }
588  }
589 }
590 
591 void Film::add_auto_pass(Scene *scene, PassType type, const char *name)
592 {
593  add_auto_pass(scene, type, PassMode::NOISY, name);
594 }
595 
596 void Film::add_auto_pass(Scene *scene, PassType type, PassMode mode, const char *name)
597 {
598  Pass *pass = new Pass();
599  pass->set_type(type);
600  pass->set_mode(mode);
601  pass->set_name(ustring((name) ? name : ""));
602  pass->is_auto_ = true;
603 
604  pass->set_owner(scene);
605  scene->passes.push_back(pass);
606 }
607 
608 void Film::remove_auto_passes(Scene *scene)
609 {
610  /* Remove all passes which were automatically created. */
611  vector<Pass *> new_passes;
612 
613  for (Pass *pass : scene->passes) {
614  if (!pass->is_auto_) {
615  new_passes.push_back(pass);
616  }
617  else {
618  delete pass;
619  }
620  }
621 
622  scene->passes = new_passes;
623 }
624 
625 static bool compare_pass_order(const Pass *a, const Pass *b)
626 {
627  /* On the highest level, sort by number of components.
628  * Within passes of the same component count, sort so that all non-lightgroup passes come first.
629  * Within that group, sort by type. */
630  const int num_components_a = a->get_info().num_components;
631  const int num_components_b = b->get_info().num_components;
632 
633  if (num_components_a == num_components_b) {
634  const int is_lightgroup_a = !a->get_lightgroup().empty();
635  const int is_lightgroup_b = !b->get_lightgroup().empty();
636  if (is_lightgroup_a == is_lightgroup_b) {
637  return (a->get_type() < b->get_type());
638  }
639  return is_lightgroup_b;
640  }
641 
642  return num_components_a > num_components_b;
643 }
644 
645 void Film::finalize_passes(Scene *scene, const bool use_denoise)
646 {
647  /* Remove duplicate passes. */
648  vector<Pass *> new_passes;
649 
650  for (Pass *pass : scene->passes) {
651  /* Disable denoising on passes if denoising is disabled, or if the
652  * pass does not support it. */
653  pass->set_mode((use_denoise && pass->get_info().support_denoise) ? pass->get_mode() :
655 
656  /* Merge duplicate passes. */
657  bool duplicate_found = false;
658  for (Pass *new_pass : new_passes) {
659  /* If different type or denoising, don't merge. */
660  if (new_pass->get_type() != pass->get_type() || new_pass->get_mode() != pass->get_mode()) {
661  continue;
662  }
663 
664  /* If both passes have a name and the names are different, don't merge.
665  * If either pass has a name, we'll use that name. */
666  if (!pass->get_name().empty() && !new_pass->get_name().empty() &&
667  pass->get_name() != new_pass->get_name()) {
668  continue;
669  }
670 
671  if (!pass->get_name().empty() && new_pass->get_name().empty()) {
672  new_pass->set_name(pass->get_name());
673  }
674 
675  new_pass->is_auto_ &= pass->is_auto_;
676  duplicate_found = true;
677  break;
678  }
679 
680  if (!duplicate_found) {
681  new_passes.push_back(pass);
682  }
683  else {
684  delete pass;
685  }
686  }
687 
688  /* Order from by components and type, This is required to for AOVs and cryptomatte passes,
689  * which the kernel assumes to be in order. Note this must use stable sort so cryptomatte
690  * passes remain in the right order. */
691  stable_sort(new_passes.begin(), new_passes.end(), compare_pass_order);
692 
693  scene->passes = new_passes;
694 }
695 
697 {
698  uint kernel_features = 0;
699 
700  for (const Pass *pass : scene->passes) {
701  if (!pass->is_written()) {
702  continue;
703  }
704 
705  const PassType pass_type = pass->get_type();
706  const PassMode pass_mode = pass->get_mode();
707 
708  if (pass_mode == PassMode::DENOISED || pass_type == PASS_DENOISING_NORMAL ||
709  pass_type == PASS_DENOISING_ALBEDO || pass_type == PASS_DENOISING_DEPTH) {
710  kernel_features |= KERNEL_FEATURE_DENOISING;
711  }
712 
713  if (pass_type >= PASS_DIFFUSE && pass_type <= PASS_VOLUME_INDIRECT) {
714  kernel_features |= KERNEL_FEATURE_LIGHT_PASSES;
715  }
716 
717  if (pass_type == PASS_SHADOW) {
718  kernel_features |= KERNEL_FEATURE_SHADOW_PASS;
719  }
720 
721  if (pass_type == PASS_AO) {
722  kernel_features |= KERNEL_FEATURE_AO_PASS;
723  }
724  }
725 
726  return kernel_features;
727 }
728 
typedef float(TangentPoint)[2]
unsigned int uint
Definition: BLI_sys_types.h:67
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
ATTR_WARN_UNUSED_RESULT const BMVert * v
bool get_baking() const
Definition: bake.cpp:25
Definition: film.h:29
int get_aov_offset(Scene *scene, string name, bool &is_color)
Definition: film.cpp:415
uint get_kernel_features(const Scene *scene) const
Definition: film.cpp:696
~Film()
Definition: film.cpp:130
static void add_default(Scene *scene)
Definition: film.cpp:134
void update_passes(Scene *scene, bool add_sample_count_pass)
Definition: film.cpp:461
void device_free(Device *device, DeviceScene *dscene, Scene *scene)
Definition: film.cpp:410
void device_update(Device *device, DeviceScene *dscene, Scene *scene)
Definition: film.cpp:140
Film()
Definition: film.cpp:126
bool update_lightgroups(Scene *scene)
Definition: film.cpp:441
void tag_update(Scene *scene, uint32_t flag)
void tag_update(Scene *scene, uint32_t flag)
Definition: integrator.cpp:291
@ AO_PASS_MODIFIED
Definition: integrator.h:87
AdaptiveSampling get_adaptive_sampling() const
Definition: integrator.cpp:329
size_t add_table(DeviceScene *dscene, vector< float > &data)
Definition: tables.cpp:60
void remove_table(size_t *offset)
Definition: tables.cpp:95
bool need_update() const
Definition: pass.h:48
PassInfo get_info() const
Definition: pass.cpp:136
static const NodeEnum * get_type_enum()
Definition: pass.cpp:44
bool is_written() const
Definition: pass.cpp:141
bool is_auto_
Definition: pass.h:70
static bool contains(const vector< Pass * > &passes, PassType type)
Definition: pass.cpp:349
bool need_update_uvs
Definition: scene/shader.h:89
#define cosf(x)
Definition: cuda/compat.h:101
#define expf(x)
Definition: cuda/compat.h:106
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
double time
Scene scene
#define function_bind
static float filter_func_gaussian(float v, float width)
Definition: film.cpp:31
static bool compare_pass_order(const Pass *a, const Pass *b)
Definition: film.cpp:625
static CCL_NAMESPACE_BEGIN float filter_func_box(float, float)
Definition: film.cpp:26
NODE_DEFINE(Film)
Definition: film.cpp:87
static float filter_func_blackman_harris(float v, float width)
Definition: film.cpp:37
static vector< float > filter_table(FilterType type, float width)
Definition: film.cpp:43
FilterType
Definition: film.h:21
@ FILTER_BOX
Definition: film.h:22
@ FILTER_BLACKMAN_HARRIS
Definition: film.h:24
@ FILTER_GAUSSIAN
Definition: film.h:23
ccl_gpu_kernel_postfix ccl_global float int int int int int int int pass_stride
#define PASS_UNUSED
Definition: kernel/types.h:44
#define FILTER_TABLE_SIZE
Definition: kernel/types.h:26
@ KERNEL_FEATURE_LIGHT_PASSES
@ KERNEL_FEATURE_AO_PASS
@ KERNEL_FEATURE_SHADOW_PASS
@ KERNEL_FEATURE_DENOISING
@ CRYPT_ASSET
Definition: kernel/types.h:411
@ CRYPT_NONE
Definition: kernel/types.h:408
@ CRYPT_ACCURATE
Definition: kernel/types.h:412
@ CRYPT_OBJECT
Definition: kernel/types.h:409
@ CRYPT_MATERIAL
Definition: kernel/types.h:410
PassType
Definition: kernel/types.h:334
@ PASS_SHADOW_CATCHER_SAMPLE_COUNT
Definition: kernel/types.h:393
@ PASS_EMISSION
Definition: kernel/types.h:339
@ PASS_POSITION
Definition: kernel/types.h:359
@ PASS_BACKGROUND
Definition: kernel/types.h:340
@ PASS_TRANSMISSION_DIRECT
Definition: kernel/types.h:350
@ PASS_VOLUME_DIRECT
Definition: kernel/types.h:353
@ PASS_UV
Definition: kernel/types.h:362
@ PASS_TRANSMISSION_COLOR
Definition: kernel/types.h:374
@ PASS_SHADOW_CATCHER_MATTE
Definition: kernel/types.h:394
@ PASS_DEPTH
Definition: kernel/types.h:358
@ PASS_MIST
Definition: kernel/types.h:376
@ PASS_TRANSMISSION_INDIRECT
Definition: kernel/types.h:351
@ PASS_SHADOW_CATCHER
Definition: kernel/types.h:392
@ PASS_DENOISING_NORMAL
Definition: kernel/types.h:377
@ PASS_ROUGHNESS
Definition: kernel/types.h:361
@ PASS_DIFFUSE_DIRECT
Definition: kernel/types.h:344
@ PASS_MOTION
Definition: kernel/types.h:365
@ PASS_CATEGORY_BAKE_END
Definition: kernel/types.h:400
@ PASS_MATERIAL_ID
Definition: kernel/types.h:364
@ PASS_AO
Definition: kernel/types.h:341
@ PASS_COMBINED
Definition: kernel/types.h:338
@ PASS_DIFFUSE
Definition: kernel/types.h:343
@ PASS_DIFFUSE_INDIRECT
Definition: kernel/types.h:345
@ PASS_CATEGORY_DATA_END
Definition: kernel/types.h:396
@ PASS_ADAPTIVE_AUX_BUFFER
Definition: kernel/types.h:370
@ PASS_OBJECT_ID
Definition: kernel/types.h:363
@ PASS_AOV_COLOR
Definition: kernel/types.h:368
@ PASS_NONE
Definition: kernel/types.h:335
@ PASS_VOLUME_INDIRECT
Definition: kernel/types.h:354
@ PASS_NORMAL
Definition: kernel/types.h:360
@ PASS_CRYPTOMATTE
Definition: kernel/types.h:367
@ PASS_DIFFUSE_COLOR
Definition: kernel/types.h:372
@ PASS_SAMPLE_COUNT
Definition: kernel/types.h:371
@ PASS_GLOSSY_DIRECT
Definition: kernel/types.h:347
@ PASS_MOTION_WEIGHT
Definition: kernel/types.h:366
@ PASS_DENOISING_ALBEDO
Definition: kernel/types.h:378
@ PASS_AOV_VALUE
Definition: kernel/types.h:369
@ PASS_GLOSSY_COLOR
Definition: kernel/types.h:373
@ PASS_SHADOW
Definition: kernel/types.h:342
@ PASS_GLOSSY_INDIRECT
Definition: kernel/types.h:348
@ PASS_BAKE_DIFFERENTIAL
Definition: kernel/types.h:399
@ PASS_DENOISING_DEPTH
Definition: kernel/types.h:379
@ PASS_BAKE_PRIMITIVE
Definition: kernel/types.h:398
@ PASS_CATEGORY_LIGHT_END
Definition: kernel/types.h:355
#define VLOG_INFO
Definition: log.h:77
#define VLOG_INFO_IS_ON
Definition: log.h:78
void util_cdf_inverted(const int resolution, const float from, const float to, Functor functor, const bool make_symmetric, vector< float > &inv_cdf)
Definition: math_cdf.h:44
static unsigned a[3]
Definition: RandGen.cpp:78
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRefNull prop_name, int32_t value)
Allocate a new IDProperty of type IDP_INT, set its name and value.
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
#define SOCKET_FLOAT(name, ui_name, default_value,...)
Definition: node_type.h:191
#define SOCKET_INT(name, ui_name, default_value,...)
Definition: node_type.h:187
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition: node_type.h:185
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition: node_type.h:207
PassMode
Definition: pass.h:19
@ TABLE_OFFSET_INVALID
Definition: scene/tables.h:17
#define min(a, b)
Definition: sort.c:35
void insert(const char *x, int y)
Definition: node_enum.h:20
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
const NodeType * type
Definition: graph/node.h:175
ustring name
Definition: graph/node.h:174
void tag_modified()
Definition: graph/node.cpp:809
bool is_modified() const
Definition: graph/node.cpp:804
void set_owner(const NodeOwner *owner_)
Definition: graph/node.cpp:773
Definition: pass.h:26
PassType direct_type
Definition: pass.h:32
int num_components
Definition: pass.h:27
bool support_denoise
Definition: pass.h:45
PassType divide_type
Definition: pass.h:31
PassType indirect_type
Definition: pass.h:33
BakeManager * bake_manager
Definition: scene.h:228
T * create_node(Args &&...args)
Definition: scene.h:284
MotionType need_motion() const
Definition: scene.cpp:387
vector< Pass * > passes
Definition: scene.h:218
vector< Shader * > shaders
Definition: scene.h:215
LookupTables * lookup_tables
Definition: scene.h:207
ObjectManager * object_manager
Definition: scene.h:226
Background * background
Definition: scene.h:209
@ MOTION_PASS
Definition: scene.h:259
bool has_shadow_catcher()
Definition: scene.cpp:737
Integrator * integrator
Definition: scene.h:210
map< ustring, int > lightgroups
Definition: scene.h:201
SceneUpdateStats * update_stats
Definition: scene.h:249
GeometryManager * geometry_manager
Definition: scene.h:225
#define M_2PI_F
Definition: util/math.h:60