Blender  V3.3
pass.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/pass.h"
5 
6 #include "util/algorithm.h"
7 #include "util/log.h"
8 
10 
11 const char *pass_type_as_string(const PassType type)
12 {
13  const int type_int = static_cast<int>(type);
14 
15  const NodeEnum *type_enum = Pass::get_type_enum();
16 
17  if (!type_enum->exists(type_int)) {
18  LOG(DFATAL) << "Unhandled pass type " << static_cast<int>(type) << ", not supposed to happen.";
19  return "UNKNOWN";
20  }
21 
22  return (*type_enum)[type_int].c_str();
23 }
24 
25 const char *pass_mode_as_string(PassMode mode)
26 {
27  switch (mode) {
28  case PassMode::NOISY:
29  return "NOISY";
30  case PassMode::DENOISED:
31  return "DENOISED";
32  }
33 
34  LOG(DFATAL) << "Unhandled pass mode " << static_cast<int>(mode) << ", should never happen.";
35  return "UNKNOWN";
36 }
37 
38 std::ostream &operator<<(std::ostream &os, PassMode mode)
39 {
40  os << pass_mode_as_string(mode);
41  return os;
42 }
43 
45 {
46  static NodeEnum pass_type_enum;
47 
48  if (pass_type_enum.empty()) {
49 
50  /* Light Passes. */
51  pass_type_enum.insert("combined", PASS_COMBINED);
52  pass_type_enum.insert("emission", PASS_EMISSION);
53  pass_type_enum.insert("background", PASS_BACKGROUND);
54  pass_type_enum.insert("ao", PASS_AO);
55  pass_type_enum.insert("shadow", PASS_SHADOW);
56  pass_type_enum.insert("diffuse", PASS_DIFFUSE);
57  pass_type_enum.insert("diffuse_direct", PASS_DIFFUSE_DIRECT);
58  pass_type_enum.insert("diffuse_indirect", PASS_DIFFUSE_INDIRECT);
59  pass_type_enum.insert("glossy", PASS_GLOSSY);
60  pass_type_enum.insert("glossy_direct", PASS_GLOSSY_DIRECT);
61  pass_type_enum.insert("glossy_indirect", PASS_GLOSSY_INDIRECT);
62  pass_type_enum.insert("transmission", PASS_TRANSMISSION);
63  pass_type_enum.insert("transmission_direct", PASS_TRANSMISSION_DIRECT);
64  pass_type_enum.insert("transmission_indirect", PASS_TRANSMISSION_INDIRECT);
65  pass_type_enum.insert("volume", PASS_VOLUME);
66  pass_type_enum.insert("volume_direct", PASS_VOLUME_DIRECT);
67  pass_type_enum.insert("volume_indirect", PASS_VOLUME_INDIRECT);
68 
69  /* Data passes. */
70  pass_type_enum.insert("depth", PASS_DEPTH);
71  pass_type_enum.insert("position", PASS_POSITION);
72  pass_type_enum.insert("normal", PASS_NORMAL);
73  pass_type_enum.insert("roughness", PASS_ROUGHNESS);
74  pass_type_enum.insert("uv", PASS_UV);
75  pass_type_enum.insert("object_id", PASS_OBJECT_ID);
76  pass_type_enum.insert("material_id", PASS_MATERIAL_ID);
77  pass_type_enum.insert("motion", PASS_MOTION);
78  pass_type_enum.insert("motion_weight", PASS_MOTION_WEIGHT);
79  pass_type_enum.insert("cryptomatte", PASS_CRYPTOMATTE);
80  pass_type_enum.insert("aov_color", PASS_AOV_COLOR);
81  pass_type_enum.insert("aov_value", PASS_AOV_VALUE);
82  pass_type_enum.insert("adaptive_aux_buffer", PASS_ADAPTIVE_AUX_BUFFER);
83  pass_type_enum.insert("sample_count", PASS_SAMPLE_COUNT);
84  pass_type_enum.insert("diffuse_color", PASS_DIFFUSE_COLOR);
85  pass_type_enum.insert("glossy_color", PASS_GLOSSY_COLOR);
86  pass_type_enum.insert("transmission_color", PASS_TRANSMISSION_COLOR);
87  pass_type_enum.insert("mist", PASS_MIST);
88  pass_type_enum.insert("denoising_normal", PASS_DENOISING_NORMAL);
89  pass_type_enum.insert("denoising_albedo", PASS_DENOISING_ALBEDO);
90  pass_type_enum.insert("denoising_depth", PASS_DENOISING_DEPTH);
91  pass_type_enum.insert("denoising_previous", PASS_DENOISING_PREVIOUS);
92 
93  pass_type_enum.insert("shadow_catcher", PASS_SHADOW_CATCHER);
94  pass_type_enum.insert("shadow_catcher_sample_count", PASS_SHADOW_CATCHER_SAMPLE_COUNT);
95  pass_type_enum.insert("shadow_catcher_matte", PASS_SHADOW_CATCHER_MATTE);
96 
97  pass_type_enum.insert("bake_primitive", PASS_BAKE_PRIMITIVE);
98  pass_type_enum.insert("bake_differential", PASS_BAKE_DIFFERENTIAL);
99  }
100 
101  return &pass_type_enum;
102 }
103 
105 {
106  static NodeEnum pass_mode_enum;
107 
108  if (pass_mode_enum.empty()) {
109  pass_mode_enum.insert("noisy", static_cast<int>(PassMode::NOISY));
110  pass_mode_enum.insert("denoised", static_cast<int>(PassMode::DENOISED));
111  }
112 
113  return &pass_mode_enum;
114 }
115 
117 {
118  NodeType *type = NodeType::add("pass", create);
119 
120  const NodeEnum *pass_type_enum = get_type_enum();
121  const NodeEnum *pass_mode_enum = get_mode_enum();
122 
123  SOCKET_ENUM(type, "Type", *pass_type_enum, PASS_COMBINED);
124  SOCKET_ENUM(mode, "Mode", *pass_mode_enum, static_cast<int>(PassMode::DENOISED));
125  SOCKET_STRING(name, "Name", ustring());
126  SOCKET_BOOLEAN(include_albedo, "Include Albedo", false);
127  SOCKET_STRING(lightgroup, "Light Group", ustring());
128 
129  return type;
130 }
131 
132 Pass::Pass() : Node(get_node_type()), is_auto_(false)
133 {
134 }
135 
137 {
138  return get_info(type, include_albedo, !lightgroup.empty());
139 }
140 
141 bool Pass::is_written() const
142 {
143  return get_info().is_written;
144 }
145 
146 PassInfo Pass::get_info(const PassType type, const bool include_albedo, const bool is_lightgroup)
147 {
148  PassInfo pass_info;
149 
150  pass_info.use_filter = true;
151  pass_info.use_exposure = false;
152  pass_info.divide_type = PASS_NONE;
153  pass_info.use_compositing = false;
154  pass_info.use_denoising_albedo = true;
155 
156  switch (type) {
157  case PASS_NONE:
158  pass_info.num_components = 0;
159  break;
160  case PASS_COMBINED:
161  pass_info.num_components = is_lightgroup ? 3 : 4;
162  pass_info.use_exposure = true;
163  pass_info.support_denoise = !is_lightgroup;
164  break;
165  case PASS_DEPTH:
166  pass_info.num_components = 1;
167  pass_info.use_filter = false;
168  break;
169  case PASS_MIST:
170  pass_info.num_components = 1;
171  break;
172  case PASS_POSITION:
173  pass_info.num_components = 3;
174  pass_info.use_filter = false;
175  break;
176  case PASS_NORMAL:
177  pass_info.num_components = 3;
178  break;
179  case PASS_ROUGHNESS:
180  pass_info.num_components = 1;
181  break;
182  case PASS_UV:
183  pass_info.num_components = 3;
184  break;
185  case PASS_MOTION:
186  pass_info.num_components = 4;
187  pass_info.divide_type = PASS_MOTION_WEIGHT;
188  break;
189  case PASS_MOTION_WEIGHT:
190  pass_info.num_components = 1;
191  break;
192  case PASS_OBJECT_ID:
193  case PASS_MATERIAL_ID:
194  pass_info.num_components = 1;
195  pass_info.use_filter = false;
196  break;
197 
198  case PASS_EMISSION:
199  case PASS_BACKGROUND:
200  pass_info.num_components = 3;
201  pass_info.use_exposure = true;
202  break;
203  case PASS_AO:
204  pass_info.num_components = 3;
205  break;
206  case PASS_SHADOW:
207  pass_info.num_components = 3;
208  pass_info.use_exposure = false;
209  break;
210 
211  case PASS_DIFFUSE_COLOR:
212  case PASS_GLOSSY_COLOR:
214  pass_info.num_components = 3;
215  break;
216  case PASS_DIFFUSE:
217  pass_info.num_components = 3;
218  pass_info.use_exposure = true;
219  pass_info.direct_type = PASS_DIFFUSE_DIRECT;
221  pass_info.divide_type = (!include_albedo) ? PASS_DIFFUSE_COLOR : PASS_NONE;
222  pass_info.use_compositing = true;
223  pass_info.is_written = false;
224  break;
225  case PASS_DIFFUSE_DIRECT:
227  pass_info.num_components = 3;
228  pass_info.use_exposure = true;
229  pass_info.divide_type = (!include_albedo) ? PASS_DIFFUSE_COLOR : PASS_NONE;
230  pass_info.use_compositing = true;
231  break;
232  case PASS_GLOSSY:
233  pass_info.num_components = 3;
234  pass_info.use_exposure = true;
235  pass_info.direct_type = PASS_GLOSSY_DIRECT;
237  pass_info.divide_type = (!include_albedo) ? PASS_GLOSSY_COLOR : PASS_NONE;
238  pass_info.use_compositing = true;
239  pass_info.is_written = false;
240  break;
241  case PASS_GLOSSY_DIRECT:
243  pass_info.num_components = 3;
244  pass_info.use_exposure = true;
245  pass_info.divide_type = (!include_albedo) ? PASS_GLOSSY_COLOR : PASS_NONE;
246  pass_info.use_compositing = true;
247  break;
248  case PASS_TRANSMISSION:
249  pass_info.num_components = 3;
250  pass_info.use_exposure = true;
253  pass_info.divide_type = (!include_albedo) ? PASS_TRANSMISSION_COLOR : PASS_NONE;
254  pass_info.use_compositing = true;
255  pass_info.is_written = false;
256  break;
259  pass_info.num_components = 3;
260  pass_info.use_exposure = true;
261  pass_info.divide_type = (!include_albedo) ? PASS_TRANSMISSION_COLOR : PASS_NONE;
262  pass_info.use_compositing = true;
263  break;
264  case PASS_VOLUME:
265  pass_info.num_components = 3;
266  pass_info.use_exposure = true;
267  pass_info.direct_type = PASS_VOLUME_DIRECT;
269  pass_info.use_compositing = true;
270  pass_info.is_written = false;
271  break;
272  case PASS_VOLUME_DIRECT:
274  pass_info.num_components = 3;
275  pass_info.use_exposure = true;
276  break;
277 
278  case PASS_CRYPTOMATTE:
279  pass_info.num_components = 4;
280  break;
281 
283  pass_info.num_components = 3;
284  break;
286  pass_info.num_components = 3;
287  break;
289  pass_info.num_components = 1;
290  break;
292  pass_info.num_components = 3;
293  pass_info.use_exposure = true;
294  break;
295 
296  case PASS_SHADOW_CATCHER:
297  pass_info.num_components = 3;
298  pass_info.use_exposure = true;
299  pass_info.use_compositing = true;
300  pass_info.use_denoising_albedo = false;
301  pass_info.support_denoise = true;
302  break;
304  pass_info.num_components = 1;
305  break;
307  pass_info.num_components = 4;
308  pass_info.use_exposure = true;
309  pass_info.support_denoise = true;
310  /* Without shadow catcher approximation compositing is not needed.
311  * Since we don't know here whether approximation is used or not, leave the decision up to
312  * the caller which will know that. */
313  break;
314 
316  pass_info.num_components = 4;
317  break;
318  case PASS_SAMPLE_COUNT:
319  pass_info.num_components = 1;
320  pass_info.use_exposure = false;
321  break;
322 
323  case PASS_AOV_COLOR:
324  pass_info.num_components = 4;
325  break;
326  case PASS_AOV_VALUE:
327  pass_info.num_components = 1;
328  break;
329 
330  case PASS_BAKE_PRIMITIVE:
332  pass_info.num_components = 4;
333  pass_info.use_exposure = false;
334  pass_info.use_filter = false;
335  break;
336 
340  case PASS_NUM:
341  LOG(DFATAL) << "Unexpected pass type is used " << type;
342  pass_info.num_components = 0;
343  break;
344  }
345 
346  return pass_info;
347 }
348 
350 {
351  for (const Pass *pass : passes) {
352  if (pass->get_type() != type) {
353  continue;
354  }
355 
356  return true;
357  }
358 
359  return false;
360 }
361 
362 const Pass *Pass::find(const vector<Pass *> &passes, const string &name)
363 {
364  for (const Pass *pass : passes) {
365  if (pass->get_name() == name) {
366  return pass;
367  }
368  }
369 
370  return nullptr;
371 }
372 
373 const Pass *Pass::find(const vector<Pass *> &passes,
374  PassType type,
375  PassMode mode,
376  const ustring &lightgroup)
377 {
378  for (const Pass *pass : passes) {
379  if (pass->get_type() != type || pass->get_mode() != mode ||
380  pass->get_lightgroup() != lightgroup) {
381  continue;
382  }
383  return pass;
384  }
385 
386  return nullptr;
387 }
388 
389 int Pass::get_offset(const vector<Pass *> &passes, const Pass *pass)
390 {
391  int pass_offset = 0;
392 
393  for (const Pass *current_pass : passes) {
394  /* Note that pass name is allowed to be empty. This is why we check for type and mode. */
395  if (current_pass->get_type() == pass->get_type() &&
396  current_pass->get_mode() == pass->get_mode() &&
397  current_pass->get_name() == pass->get_name()) {
398  if (current_pass->is_written()) {
399  return pass_offset;
400  }
401  else {
402  return PASS_UNUSED;
403  }
404  }
405  if (current_pass->is_written()) {
406  pass_offset += current_pass->get_info().num_components;
407  }
408  }
409 
410  return PASS_UNUSED;
411 }
412 
413 std::ostream &operator<<(std::ostream &os, const Pass &pass)
414 {
415  os << "type: " << pass_type_as_string(pass.get_type());
416  os << ", name: \"" << pass.get_name() << "\"";
417  os << ", mode: " << pass.get_mode();
418  os << ", is_written: " << string_from_bool(pass.is_written());
419 
420  return os;
421 }
422 
_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
Definition: pass.h:48
PassInfo get_info() const
Definition: pass.cpp:136
static const NodeEnum * get_type_enum()
Definition: pass.cpp:44
NODE_DECLARE Pass()
Definition: pass.cpp:132
bool is_written() const
Definition: pass.cpp:141
static const NodeEnum * get_mode_enum()
Definition: pass.cpp:104
static const Pass * find(const vector< Pass * > &passes, const string &name)
Definition: pass.cpp:362
static bool contains(const vector< Pass * > &passes, PassType type)
Definition: pass.cpp:349
static int get_offset(const vector< Pass * > &passes, const Pass *pass)
Definition: pass.cpp:389
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
#define PASS_UNUSED
Definition: kernel/types.h:44
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_GLOSSY
Definition: kernel/types.h:346
@ PASS_OBJECT_ID
Definition: kernel/types.h:363
@ PASS_AOV_COLOR
Definition: kernel/types.h:368
@ PASS_NUM
Definition: kernel/types.h:402
@ PASS_NONE
Definition: kernel/types.h:335
@ PASS_VOLUME_INDIRECT
Definition: kernel/types.h:354
@ PASS_TRANSMISSION
Definition: kernel/types.h:349
@ 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_VOLUME
Definition: kernel/types.h:352
@ PASS_AOV_VALUE
Definition: kernel/types.h:369
@ PASS_GLOSSY_COLOR
Definition: kernel/types.h:373
@ PASS_SHADOW
Definition: kernel/types.h:342
@ PASS_DENOISING_PREVIOUS
Definition: kernel/types.h:380
@ 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 LOG(severity)
Definition: log.h:36
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.
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition: node_type.h:185
#define SOCKET_STRING(name, ui_name, default_value,...)
Definition: node_type.h:203
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition: node_type.h:207
const char * pass_mode_as_string(PassMode mode)
Definition: pass.cpp:25
NODE_DEFINE(Pass)
Definition: pass.cpp:116
std::ostream & operator<<(std::ostream &os, PassMode mode)
Definition: pass.cpp:38
CCL_NAMESPACE_BEGIN const char * pass_type_as_string(const PassType type)
Definition: pass.cpp:11
PassMode
Definition: pass.h:19
string string_from_bool(bool var)
Definition: string.cpp:167
bool empty() const
Definition: node_enum.h:16
void insert(const char *x, int y)
Definition: node_enum.h:20
bool exists(ustring x) const
Definition: node_enum.h:28
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
Definition: pass.h:26
PassType direct_type
Definition: pass.h:32
bool use_compositing
Definition: pass.h:37
bool use_denoising_albedo
Definition: pass.h:42
int num_components
Definition: pass.h:27
bool support_denoise
Definition: pass.h:45
bool use_filter
Definition: pass.h:28
PassType divide_type
Definition: pass.h:31
bool use_exposure
Definition: pass.h:29
PassType indirect_type
Definition: pass.h:33
bool is_written
Definition: pass.h:30