Blender V4.3
pass.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "scene/pass.h"
6
7#include "util/algorithm.h"
8#include "util/log.h"
9
11
12const char *pass_type_as_string(const PassType type)
13{
14 const int type_int = static_cast<int>(type);
15
16 const NodeEnum *type_enum = Pass::get_type_enum();
17
18 if (!type_enum->exists(type_int)) {
19 LOG(DFATAL) << "Unhandled pass type " << static_cast<int>(type) << ", not supposed to happen.";
20 return "UNKNOWN";
21 }
22
23 return (*type_enum)[type_int].c_str();
24}
25
27{
28 switch (mode) {
29 case PassMode::NOISY:
30 return "NOISY";
32 return "DENOISED";
33 }
34
35 LOG(DFATAL) << "Unhandled pass mode " << static_cast<int>(mode) << ", should never happen.";
36 return "UNKNOWN";
37}
38
39std::ostream &operator<<(std::ostream &os, PassMode mode)
40{
41 os << pass_mode_as_string(mode);
42 return os;
43}
44
46{
47 static NodeEnum pass_type_enum;
48
49 if (pass_type_enum.empty()) {
50
51 /* Light Passes. */
52 pass_type_enum.insert("combined", PASS_COMBINED);
53 pass_type_enum.insert("emission", PASS_EMISSION);
54 pass_type_enum.insert("background", PASS_BACKGROUND);
55 pass_type_enum.insert("ao", PASS_AO);
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_seed", PASS_BAKE_SEED);
99 pass_type_enum.insert("bake_differential", PASS_BAKE_DIFFERENTIAL);
100
101#ifdef WITH_CYCLES_DEBUG
102 pass_type_enum.insert("guiding_color", PASS_GUIDING_COLOR);
103 pass_type_enum.insert("guiding_probability", PASS_GUIDING_PROBABILITY);
104 pass_type_enum.insert("guiding_avg_roughness", PASS_GUIDING_AVG_ROUGHNESS);
105#endif
106 }
107
108 return &pass_type_enum;
109}
110
112{
113 static NodeEnum pass_mode_enum;
114
115 if (pass_mode_enum.empty()) {
116 pass_mode_enum.insert("noisy", static_cast<int>(PassMode::NOISY));
117 pass_mode_enum.insert("denoised", static_cast<int>(PassMode::DENOISED));
118 }
119
120 return &pass_mode_enum;
121}
122
124{
125 NodeType *type = NodeType::add("pass", create);
126
127 const NodeEnum *pass_type_enum = get_type_enum();
128 const NodeEnum *pass_mode_enum = get_mode_enum();
129
130 SOCKET_ENUM(type, "Type", *pass_type_enum, PASS_COMBINED);
131 SOCKET_ENUM(mode, "Mode", *pass_mode_enum, static_cast<int>(PassMode::DENOISED));
132 SOCKET_STRING(name, "Name", ustring());
133 SOCKET_BOOLEAN(include_albedo, "Include Albedo", false);
134 SOCKET_STRING(lightgroup, "Light Group", ustring());
135
136 return type;
137}
138
139Pass::Pass() : Node(get_node_type()), is_auto_(false) {}
140
142{
143 return get_info(type, include_albedo, !lightgroup.empty());
144}
145
147{
148 return get_info().is_written;
149}
150
151PassInfo Pass::get_info(const PassType type, const bool include_albedo, const bool is_lightgroup)
152{
153 PassInfo pass_info;
154
155 pass_info.use_filter = true;
156 pass_info.use_exposure = false;
157 pass_info.divide_type = PASS_NONE;
158 pass_info.use_compositing = false;
159 pass_info.use_denoising_albedo = true;
160
161 switch (type) {
162 case PASS_NONE:
163 pass_info.num_components = 0;
164 break;
165 case PASS_COMBINED:
166 pass_info.num_components = is_lightgroup ? 3 : 4;
167 pass_info.use_exposure = true;
168 pass_info.support_denoise = !is_lightgroup;
169 break;
170 case PASS_DEPTH:
171 pass_info.num_components = 1;
172 pass_info.use_filter = false;
173 break;
174 case PASS_MIST:
175 pass_info.num_components = 1;
176 break;
177 case PASS_POSITION:
178 pass_info.num_components = 3;
179 pass_info.use_filter = false;
180 break;
181 case PASS_NORMAL:
182 pass_info.num_components = 3;
183 break;
184 case PASS_ROUGHNESS:
185 pass_info.num_components = 1;
186 break;
187 case PASS_UV:
188 pass_info.num_components = 3;
189 break;
190 case PASS_MOTION:
191 pass_info.num_components = 4;
193 break;
195 pass_info.num_components = 1;
196 break;
197 case PASS_OBJECT_ID:
198 case PASS_MATERIAL_ID:
199 pass_info.num_components = 1;
200 pass_info.use_filter = false;
201 break;
202
203 case PASS_EMISSION:
204 case PASS_BACKGROUND:
205 pass_info.num_components = 3;
206 pass_info.use_exposure = true;
207 break;
208 case PASS_AO:
209 pass_info.num_components = 3;
210 break;
211
215 pass_info.num_components = 3;
216 break;
217 case PASS_DIFFUSE:
218 pass_info.num_components = 3;
219 pass_info.use_exposure = true;
222 pass_info.divide_type = (!include_albedo) ? PASS_DIFFUSE_COLOR : PASS_NONE;
223 pass_info.use_compositing = true;
224 pass_info.is_written = false;
225 break;
228 pass_info.num_components = 3;
229 pass_info.use_exposure = true;
230 pass_info.divide_type = (!include_albedo) ? PASS_DIFFUSE_COLOR : PASS_NONE;
231 pass_info.use_compositing = true;
232 break;
233 case PASS_GLOSSY:
234 pass_info.num_components = 3;
235 pass_info.use_exposure = true;
238 pass_info.divide_type = (!include_albedo) ? PASS_GLOSSY_COLOR : PASS_NONE;
239 pass_info.use_compositing = true;
240 pass_info.is_written = false;
241 break;
244 pass_info.num_components = 3;
245 pass_info.use_exposure = true;
246 pass_info.divide_type = (!include_albedo) ? PASS_GLOSSY_COLOR : PASS_NONE;
247 pass_info.use_compositing = true;
248 break;
250 pass_info.num_components = 3;
251 pass_info.use_exposure = true;
254 pass_info.divide_type = (!include_albedo) ? PASS_TRANSMISSION_COLOR : PASS_NONE;
255 pass_info.use_compositing = true;
256 pass_info.is_written = false;
257 break;
260 pass_info.num_components = 3;
261 pass_info.use_exposure = true;
262 pass_info.divide_type = (!include_albedo) ? PASS_TRANSMISSION_COLOR : PASS_NONE;
263 pass_info.use_compositing = true;
264 break;
265 case PASS_VOLUME:
266 pass_info.num_components = 3;
267 pass_info.use_exposure = true;
270 pass_info.use_compositing = true;
271 pass_info.is_written = false;
272 break;
275 pass_info.num_components = 3;
276 pass_info.use_exposure = true;
277 break;
278
279 case PASS_CRYPTOMATTE:
280 pass_info.num_components = 4;
281 break;
282
284 pass_info.num_components = 3;
285 break;
287 pass_info.num_components = 3;
288 break;
290 pass_info.num_components = 1;
291 break;
293 pass_info.num_components = 3;
294 pass_info.use_exposure = true;
295 break;
296
298 pass_info.num_components = 3;
299 pass_info.use_exposure = true;
300 pass_info.use_compositing = true;
301 pass_info.use_denoising_albedo = false;
302 pass_info.support_denoise = true;
303 break;
305 pass_info.num_components = 1;
306 break;
308 pass_info.num_components = 4;
309 pass_info.use_exposure = true;
310 pass_info.support_denoise = true;
311 /* Without shadow catcher approximation compositing is not needed.
312 * Since we don't know here whether approximation is used or not, leave the decision up to
313 * the caller which will know that. */
314 break;
315
317 pass_info.num_components = 4;
318 break;
320 pass_info.num_components = 1;
321 pass_info.use_exposure = false;
322 break;
323
324 case PASS_AOV_COLOR:
325 pass_info.num_components = 4;
326 break;
327 case PASS_AOV_VALUE:
328 pass_info.num_components = 1;
329 break;
330
332 pass_info.num_components = 3;
333 pass_info.use_exposure = false;
334 pass_info.use_filter = false;
335 break;
336 case PASS_BAKE_SEED:
337 pass_info.num_components = 1;
338 pass_info.use_exposure = false;
339 pass_info.use_filter = false;
340 break;
342 pass_info.num_components = 4;
343 pass_info.use_exposure = false;
344 pass_info.use_filter = false;
345 break;
346
350 case PASS_NUM:
351 LOG(DFATAL) << "Unexpected pass type is used " << type;
352 pass_info.num_components = 0;
353 break;
355 pass_info.num_components = 3;
356 break;
358 pass_info.num_components = 1;
359 break;
361 pass_info.num_components = 1;
362 break;
363 }
364
365 return pass_info;
366}
367
368bool Pass::contains(const vector<Pass *> &passes, PassType type)
369{
370 for (const Pass *pass : passes) {
371 if (pass->get_type() != type) {
372 continue;
373 }
374
375 return true;
376 }
377
378 return false;
379}
380
381const Pass *Pass::find(const vector<Pass *> &passes, const string &name)
382{
383 for (const Pass *pass : passes) {
384 if (pass->get_name() == name) {
385 return pass;
386 }
387 }
388
389 return nullptr;
390}
391
392const Pass *Pass::find(const vector<Pass *> &passes,
393 PassType type,
394 PassMode mode,
395 const ustring &lightgroup)
396{
397 for (const Pass *pass : passes) {
398 if (pass->get_type() != type || pass->get_mode() != mode ||
399 pass->get_lightgroup() != lightgroup)
400 {
401 continue;
402 }
403 return pass;
404 }
405
406 return nullptr;
407}
408
409int Pass::get_offset(const vector<Pass *> &passes, const Pass *pass)
410{
411 int pass_offset = 0;
412
413 for (const Pass *current_pass : passes) {
414 /* Note that pass name is allowed to be empty. This is why we check for type and mode. */
415 if (current_pass->get_type() == pass->get_type() &&
416 current_pass->get_mode() == pass->get_mode() &&
417 current_pass->get_name() == pass->get_name())
418 {
419 if (current_pass->is_written()) {
420 return pass_offset;
421 }
422 else {
423 return PASS_UNUSED;
424 }
425 }
426 if (current_pass->is_written()) {
427 pass_offset += current_pass->get_info().num_components;
428 }
429 }
430
431 return PASS_UNUSED;
432}
433
434std::ostream &operator<<(std::ostream &os, const Pass &pass)
435{
436 os << "type: " << pass_type_as_string(pass.get_type());
437 os << ", name: \"" << pass.get_name() << "\"";
438 os << ", mode: " << pass.get_mode();
439 os << ", is_written: " << string_from_bool(pass.is_written());
440
441 return os;
442}
443
Definition pass.h:49
PassInfo get_info() const
Definition pass.cpp:141
static const NodeEnum * get_type_enum()
Definition pass.cpp:45
NODE_DECLARE Pass()
Definition pass.cpp:139
bool is_written() const
Definition pass.cpp:146
static const NodeEnum * get_mode_enum()
Definition pass.cpp:111
static const Pass * find(const vector< Pass * > &passes, const string &name)
Definition pass.cpp:381
static bool contains(const vector< Pass * > &passes, PassType type)
Definition pass.cpp:368
static int get_offset(const vector< Pass * > &passes, const Pass *pass)
Definition pass.cpp:409
#define CCL_NAMESPACE_END
#define PASS_UNUSED
PassType
@ PASS_SHADOW_CATCHER_SAMPLE_COUNT
@ PASS_EMISSION
@ PASS_POSITION
@ PASS_BACKGROUND
@ PASS_TRANSMISSION_DIRECT
@ PASS_VOLUME_DIRECT
@ PASS_UV
@ PASS_TRANSMISSION_COLOR
@ PASS_SHADOW_CATCHER_MATTE
@ PASS_GUIDING_COLOR
@ PASS_DEPTH
@ PASS_MIST
@ PASS_TRANSMISSION_INDIRECT
@ PASS_BAKE_SEED
@ PASS_SHADOW_CATCHER
@ PASS_DENOISING_NORMAL
@ PASS_ROUGHNESS
@ PASS_DIFFUSE_DIRECT
@ PASS_MOTION
@ PASS_CATEGORY_BAKE_END
@ PASS_MATERIAL_ID
@ PASS_AO
@ PASS_COMBINED
@ PASS_DIFFUSE
@ PASS_DIFFUSE_INDIRECT
@ PASS_GUIDING_PROBABILITY
@ PASS_CATEGORY_DATA_END
@ PASS_ADAPTIVE_AUX_BUFFER
@ PASS_GLOSSY
@ PASS_OBJECT_ID
@ PASS_AOV_COLOR
@ PASS_NUM
@ PASS_NONE
@ PASS_VOLUME_INDIRECT
@ PASS_TRANSMISSION
@ PASS_NORMAL
@ PASS_CRYPTOMATTE
@ PASS_DIFFUSE_COLOR
@ PASS_SAMPLE_COUNT
@ PASS_GLOSSY_DIRECT
@ PASS_MOTION_WEIGHT
@ PASS_DENOISING_ALBEDO
@ PASS_VOLUME
@ PASS_AOV_VALUE
@ PASS_GUIDING_AVG_ROUGHNESS
@ PASS_GLOSSY_COLOR
@ PASS_DENOISING_PREVIOUS
@ PASS_GLOSSY_INDIRECT
@ PASS_BAKE_DIFFERENTIAL
@ PASS_DENOISING_DEPTH
@ PASS_BAKE_PRIMITIVE
@ PASS_CATEGORY_LIGHT_END
#define LOG(severity)
Definition log.h:33
#define NODE_DEFINE(structname)
Definition node_type.h:148
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition node_type.h:192
#define SOCKET_STRING(name, ui_name, default_value,...)
Definition node_type.h:212
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition node_type.h:216
const char * pass_mode_as_string(PassMode mode)
Definition pass.cpp:26
CCL_NAMESPACE_BEGIN const char * pass_type_as_string(const PassType type)
Definition pass.cpp:12
std::ostream & operator<<(std::ostream &os, PassMode mode)
Definition pass.cpp:39
PassMode
Definition pass.h:20
string string_from_bool(bool var)
Definition string.cpp:170
bool empty() const
Definition node_enum.h:17
void insert(const char *x, int y)
Definition node_enum.h:21
bool exists(ustring x) const
Definition node_enum.h:29
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
const NodeType * type
Definition graph/node.h:178
ustring name
Definition graph/node.h:177
PassType direct_type
Definition pass.h:33
bool use_compositing
Definition pass.h:38
bool use_denoising_albedo
Definition pass.h:43
int num_components
Definition pass.h:28
bool support_denoise
Definition pass.h:46
bool use_filter
Definition pass.h:29
PassType divide_type
Definition pass.h:32
bool use_exposure
Definition pass.h:30
PassType indirect_type
Definition pass.h:34
bool is_written
Definition pass.h:31