Blender V5.0
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/log.h"
8#include "util/time.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 pass_type_enum.insert("volume_scatter", PASS_VOLUME_SCATTER);
69 pass_type_enum.insert("volume_transmit", PASS_VOLUME_TRANSMIT);
70
71 /* Data passes. */
72 pass_type_enum.insert("depth", PASS_DEPTH);
73 pass_type_enum.insert("position", PASS_POSITION);
74 pass_type_enum.insert("normal", PASS_NORMAL);
75 pass_type_enum.insert("roughness", PASS_ROUGHNESS);
76 pass_type_enum.insert("uv", PASS_UV);
77 pass_type_enum.insert("object_id", PASS_OBJECT_ID);
78 pass_type_enum.insert("material_id", PASS_MATERIAL_ID);
79 pass_type_enum.insert("motion", PASS_MOTION);
80 pass_type_enum.insert("motion_weight", PASS_MOTION_WEIGHT);
81 pass_type_enum.insert("cryptomatte", PASS_CRYPTOMATTE);
82 pass_type_enum.insert("aov_color", PASS_AOV_COLOR);
83 pass_type_enum.insert("aov_value", PASS_AOV_VALUE);
84 pass_type_enum.insert("adaptive_aux_buffer", PASS_ADAPTIVE_AUX_BUFFER);
85 pass_type_enum.insert("sample_count", PASS_SAMPLE_COUNT);
86 pass_type_enum.insert("diffuse_color", PASS_DIFFUSE_COLOR);
87 pass_type_enum.insert("glossy_color", PASS_GLOSSY_COLOR);
88 pass_type_enum.insert("transmission_color", PASS_TRANSMISSION_COLOR);
89 pass_type_enum.insert("mist", PASS_MIST);
90 pass_type_enum.insert("denoising_normal", PASS_DENOISING_NORMAL);
91 pass_type_enum.insert("denoising_albedo", PASS_DENOISING_ALBEDO);
92 pass_type_enum.insert("denoising_depth", PASS_DENOISING_DEPTH);
93 pass_type_enum.insert("denoising_previous", PASS_DENOISING_PREVIOUS);
94 pass_type_enum.insert("volume_majorant", PASS_VOLUME_MAJORANT);
95 pass_type_enum.insert("volume_majorant_sample_count", PASS_VOLUME_MAJORANT_SAMPLE_COUNT);
96 pass_type_enum.insert("render_time", PASS_RENDER_TIME);
97
98 pass_type_enum.insert("shadow_catcher", PASS_SHADOW_CATCHER);
99 pass_type_enum.insert("shadow_catcher_sample_count", PASS_SHADOW_CATCHER_SAMPLE_COUNT);
100 pass_type_enum.insert("shadow_catcher_matte", PASS_SHADOW_CATCHER_MATTE);
101
102 pass_type_enum.insert("bake_primitive", PASS_BAKE_PRIMITIVE);
103 pass_type_enum.insert("bake_seed", PASS_BAKE_SEED);
104 pass_type_enum.insert("bake_differential", PASS_BAKE_DIFFERENTIAL);
105
106#ifdef WITH_CYCLES_DEBUG
107 pass_type_enum.insert("guiding_color", PASS_GUIDING_COLOR);
108 pass_type_enum.insert("guiding_probability", PASS_GUIDING_PROBABILITY);
109 pass_type_enum.insert("guiding_avg_roughness", PASS_GUIDING_AVG_ROUGHNESS);
110#endif
111 }
112
113 return &pass_type_enum;
114}
115
117{
118 static NodeEnum pass_mode_enum;
119
120 if (pass_mode_enum.empty()) {
121 pass_mode_enum.insert("noisy", static_cast<int>(PassMode::NOISY));
122 pass_mode_enum.insert("denoised", static_cast<int>(PassMode::DENOISED));
123 }
124
125 return &pass_mode_enum;
126}
127
129{
130 NodeType *type = NodeType::add("pass", create);
131
132 const NodeEnum *pass_type_enum = get_type_enum();
133 const NodeEnum *pass_mode_enum = get_mode_enum();
134
135 SOCKET_ENUM(type, "Type", *pass_type_enum, PASS_COMBINED);
136 SOCKET_ENUM(mode, "Mode", *pass_mode_enum, static_cast<int>(PassMode::DENOISED));
137 SOCKET_STRING(name, "Name", ustring());
138 SOCKET_BOOLEAN(include_albedo, "Include Albedo", false);
139 SOCKET_STRING(lightgroup, "Light Group", ustring());
140
141 return type;
142}
143
144Pass::Pass() : Node(get_node_type()), is_auto_(false) {}
145
147{
148 return get_info(type, mode, include_albedo, !lightgroup.empty());
149}
150
152{
153 return get_info().is_written;
154}
155
157 const PassMode mode,
158 const bool include_albedo,
159 const bool is_lightgroup)
160{
161 PassInfo pass_info;
162
163 pass_info.use_filter = true;
164 pass_info.use_exposure = false;
165 pass_info.divide_type = PASS_NONE;
166 pass_info.use_compositing = false;
167 pass_info.use_denoising_albedo = true;
168
169 switch (type) {
170 case PASS_NONE:
171 pass_info.num_components = 0;
172 break;
173 case PASS_COMBINED:
174 pass_info.num_components = is_lightgroup ? 3 : 4;
175 pass_info.use_exposure = true;
176 pass_info.support_denoise = !is_lightgroup;
177 break;
178 case PASS_DEPTH:
179 pass_info.num_components = 1;
180 pass_info.use_filter = false;
181 break;
182 case PASS_MIST:
183 pass_info.num_components = 1;
184 break;
185 case PASS_POSITION:
186 pass_info.num_components = 3;
187 pass_info.use_filter = false;
188 break;
189 case PASS_NORMAL:
190 pass_info.num_components = 3;
191 break;
192 case PASS_ROUGHNESS:
193 pass_info.num_components = 1;
194 break;
195 case PASS_UV:
196 pass_info.num_components = 3;
197 break;
198 case PASS_MOTION:
199 pass_info.num_components = 4;
201 break;
203 pass_info.num_components = 1;
204 break;
205 case PASS_OBJECT_ID:
206 case PASS_MATERIAL_ID:
207 pass_info.num_components = 1;
208 pass_info.use_filter = false;
209 break;
210
211 case PASS_EMISSION:
212 case PASS_BACKGROUND:
213 pass_info.num_components = 3;
214 pass_info.use_exposure = true;
215 break;
216 case PASS_AO:
217 pass_info.num_components = 3;
218 break;
219
223 pass_info.num_components = 3;
224 break;
225 case PASS_DIFFUSE:
226 pass_info.num_components = 3;
227 pass_info.use_exposure = true;
230 pass_info.divide_type = (!include_albedo) ? PASS_DIFFUSE_COLOR : PASS_NONE;
231 pass_info.use_compositing = true;
232 pass_info.is_written = false;
233 break;
236 pass_info.num_components = 3;
237 pass_info.use_exposure = true;
238 pass_info.divide_type = (!include_albedo) ? PASS_DIFFUSE_COLOR : PASS_NONE;
239 pass_info.use_compositing = true;
240 break;
241 case PASS_GLOSSY:
242 pass_info.num_components = 3;
243 pass_info.use_exposure = true;
246 pass_info.divide_type = (!include_albedo) ? PASS_GLOSSY_COLOR : PASS_NONE;
247 pass_info.use_compositing = true;
248 pass_info.is_written = false;
249 break;
252 pass_info.num_components = 3;
253 pass_info.use_exposure = true;
254 pass_info.divide_type = (!include_albedo) ? PASS_GLOSSY_COLOR : PASS_NONE;
255 pass_info.use_compositing = true;
256 break;
258 pass_info.num_components = 3;
259 pass_info.use_exposure = true;
262 pass_info.divide_type = (!include_albedo) ? PASS_TRANSMISSION_COLOR : PASS_NONE;
263 pass_info.use_compositing = true;
264 pass_info.is_written = false;
265 break;
268 pass_info.num_components = 3;
269 pass_info.use_exposure = true;
270 pass_info.divide_type = (!include_albedo) ? PASS_TRANSMISSION_COLOR : PASS_NONE;
271 pass_info.use_compositing = true;
272 break;
273 case PASS_VOLUME:
274 pass_info.num_components = 3;
275 pass_info.use_exposure = true;
278 pass_info.use_compositing = true;
279 pass_info.is_written = false;
280 break;
283 pass_info.num_components = 3;
284 pass_info.use_exposure = true;
285 break;
288 /* Noisy buffer needs higher precision for accumulating the contribution, denoised buffer is
289 * used directly and thus can have lower resolution. */
290 pass_info.num_components = (mode == PassMode::NOISY) ? 3 : 1;
291 pass_info.use_exposure = true;
292 pass_info.use_filter = false;
293 pass_info.support_denoise = true;
294 break;
296 pass_info.num_components = 1;
297 pass_info.use_filter = false;
299 break;
301 pass_info.num_components = 1;
302 pass_info.use_filter = false;
303 break;
304
305 case PASS_CRYPTOMATTE:
306 pass_info.num_components = 4;
307 break;
308
310 pass_info.num_components = 3;
311 break;
313 pass_info.num_components = 3;
314 break;
316 pass_info.num_components = 1;
317 break;
319 pass_info.num_components = 3;
320 pass_info.use_exposure = true;
321 break;
322
324 pass_info.num_components = 3;
325 pass_info.use_exposure = true;
326 pass_info.use_compositing = true;
327 pass_info.use_denoising_albedo = false;
328 pass_info.support_denoise = true;
329 break;
331 pass_info.num_components = 1;
332 break;
334 pass_info.num_components = 4;
335 pass_info.use_exposure = true;
336 pass_info.support_denoise = true;
337 /* Without shadow catcher approximation compositing is not needed.
338 * Since we don't know here whether approximation is used or not, leave the decision up to
339 * the caller which will know that. */
340 break;
341
343 pass_info.num_components = 4;
344 break;
346 pass_info.num_components = 1;
347 pass_info.use_exposure = false;
348 break;
349 case PASS_RENDER_TIME:
350 pass_info.num_components = 1;
351 pass_info.use_exposure = false;
352 pass_info.use_filter = false;
353 pass_info.scale = 1000.0f / float(time_fast_frequency());
354 break;
355
356 case PASS_AOV_COLOR:
357 pass_info.num_components = 4;
358 break;
359 case PASS_AOV_VALUE:
360 pass_info.num_components = 1;
361 break;
362
364 pass_info.num_components = 3;
365 pass_info.use_exposure = false;
366 pass_info.use_filter = false;
367 break;
368 case PASS_BAKE_SEED:
369 pass_info.num_components = 1;
370 pass_info.use_exposure = false;
371 pass_info.use_filter = false;
372 break;
374 pass_info.num_components = 4;
375 pass_info.use_exposure = false;
376 pass_info.use_filter = false;
377 break;
378
382 case PASS_NUM:
383 LOG_DFATAL << "Unexpected pass type is used " << type;
384 pass_info.num_components = 0;
385 break;
387 pass_info.num_components = 3;
388 break;
390 pass_info.num_components = 1;
391 break;
393 pass_info.num_components = 1;
394 break;
395 }
396
397 return pass_info;
398}
399
401{
402 for (const Pass *pass : passes) {
403 if (pass->get_type() != type) {
404 continue;
405 }
406
407 return true;
408 }
409
410 return false;
411}
412
413const Pass *Pass::find(const unique_ptr_vector<Pass> &passes, const string &name)
414{
415 for (const Pass *pass : passes) {
416 if (pass->get_name() == name) {
417 return pass;
418 }
419 }
420
421 return nullptr;
422}
423
426 PassMode mode,
427 const ustring &lightgroup)
428{
429 for (const Pass *pass : passes) {
430 if (pass->get_type() != type || pass->get_mode() != mode ||
431 pass->get_lightgroup() != lightgroup)
432 {
433 continue;
434 }
435 return pass;
436 }
437
438 return nullptr;
439}
440
441int Pass::get_offset(const unique_ptr_vector<Pass> &passes, const Pass *pass)
442{
443 int pass_offset = 0;
444
445 for (const Pass *current_pass : passes) {
446 /* Note that pass name is allowed to be empty. This is why we check for type and mode. */
447 if (current_pass->get_type() == pass->get_type() &&
448 current_pass->get_mode() == pass->get_mode() &&
449 current_pass->get_name() == pass->get_name())
450 {
451 if (current_pass->is_written()) {
452 return pass_offset;
453 }
454 return PASS_UNUSED;
455 }
456 if (current_pass->is_written()) {
457 pass_offset += current_pass->get_info().num_components;
458 }
459 }
460
461 return PASS_UNUSED;
462}
463
464std::ostream &operator<<(std::ostream &os, const Pass &pass)
465{
466 os << "type: " << pass_type_as_string(pass.get_type());
467 os << ", name: \"" << pass.get_name() << "\"";
468 os << ", mode: " << pass.get_mode();
469 os << ", is_written: " << string_from_bool(pass.is_written());
470
471 return os;
472}
473
474bool is_volume_guiding_pass(const PassType pass_type)
475{
476 return (pass_type == PASS_VOLUME_SCATTER) || (pass_type == PASS_VOLUME_TRANSMIT);
477}
478
Definition pass.h:50
static const Pass * find(const unique_ptr_vector< Pass > &passes, const string &name)
Definition pass.cpp:413
PassInfo get_info() const
Definition pass.cpp:146
static int get_offset(const unique_ptr_vector< Pass > &passes, const Pass *pass)
Definition pass.cpp:441
static bool contains(const unique_ptr_vector< Pass > &passes, PassType type)
Definition pass.cpp:400
static const NodeEnum * get_type_enum()
Definition pass.cpp:45
NODE_DECLARE Pass()
Definition pass.cpp:144
bool is_written() const
Definition pass.cpp:151
static const NodeEnum * get_mode_enum()
Definition pass.cpp:116
bool is_auto_
Definition pass.h:72
nullptr float
#define PASS_UNUSED
#define CCL_NAMESPACE_END
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_VOLUME_SCATTER
@ PASS_TRANSMISSION_INDIRECT
@ PASS_BAKE_SEED
@ PASS_SHADOW_CATCHER
@ PASS_VOLUME_MAJORANT
@ PASS_DENOISING_NORMAL
@ PASS_ROUGHNESS
@ PASS_DIFFUSE_DIRECT
@ PASS_MOTION
@ PASS_CATEGORY_BAKE_END
@ PASS_MATERIAL_ID
@ PASS_VOLUME_MAJORANT_SAMPLE_COUNT
@ PASS_AO
@ PASS_COMBINED
@ PASS_DIFFUSE
@ PASS_DIFFUSE_INDIRECT
@ PASS_RENDER_TIME
@ 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_VOLUME_TRANSMIT
@ PASS_DENOISING_DEPTH
@ PASS_BAKE_PRIMITIVE
@ PASS_CATEGORY_LIGHT_END
#define LOG_DFATAL
Definition log.h:100
#define NODE_DEFINE(structname)
Definition node_type.h:152
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition node_type.h:203
#define SOCKET_STRING(name, ui_name, default_value,...)
Definition node_type.h:223
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition node_type.h:227
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
bool is_volume_guiding_pass(const PassType pass_type)
Definition pass.cpp:474
PassMode
Definition pass.h:20
@ DENOISED
Definition pass.h:22
@ NOISY
Definition pass.h:21
const char * name
string string_from_bool(bool var)
Definition string.cpp:183
void insert(const char *x, const int y)
Definition node_enum.h:21
bool empty() const
Definition node_enum.h:17
bool exists(ustring x) const
Definition node_enum.h:29
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=nullptr)
const NodeType * type
Definition graph/node.h:178
ustring name
Definition graph/node.h:177
Node(const NodeType *type, ustring name=ustring())
PassType direct_type
Definition pass.h:34
bool use_compositing
Definition pass.h:39
bool use_denoising_albedo
Definition pass.h:44
int num_components
Definition pass.h:28
float scale
Definition pass.h:32
bool support_denoise
Definition pass.h:47
bool use_filter
Definition pass.h:29
PassType divide_type
Definition pass.h:33
bool use_exposure
Definition pass.h:30
PassType indirect_type
Definition pass.h:35
bool is_written
Definition pass.h:31
uint64_t time_fast_frequency()
Definition time.cpp:135