Blender V4.5
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
10
11const 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
26{
27 switch (mode) {
28 case PassMode::NOISY:
29 return "NOISY";
31 return "DENOISED";
32 }
33
34 LOG(DFATAL) << "Unhandled pass mode " << static_cast<int>(mode) << ", should never happen.";
35 return "UNKNOWN";
36}
37
38std::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("diffuse", PASS_DIFFUSE);
56 pass_type_enum.insert("diffuse_direct", PASS_DIFFUSE_DIRECT);
57 pass_type_enum.insert("diffuse_indirect", PASS_DIFFUSE_INDIRECT);
58 pass_type_enum.insert("glossy", PASS_GLOSSY);
59 pass_type_enum.insert("glossy_direct", PASS_GLOSSY_DIRECT);
60 pass_type_enum.insert("glossy_indirect", PASS_GLOSSY_INDIRECT);
61 pass_type_enum.insert("transmission", PASS_TRANSMISSION);
62 pass_type_enum.insert("transmission_direct", PASS_TRANSMISSION_DIRECT);
63 pass_type_enum.insert("transmission_indirect", PASS_TRANSMISSION_INDIRECT);
64 pass_type_enum.insert("volume", PASS_VOLUME);
65 pass_type_enum.insert("volume_direct", PASS_VOLUME_DIRECT);
66 pass_type_enum.insert("volume_indirect", PASS_VOLUME_INDIRECT);
67
68 /* Data passes. */
69 pass_type_enum.insert("depth", PASS_DEPTH);
70 pass_type_enum.insert("position", PASS_POSITION);
71 pass_type_enum.insert("normal", PASS_NORMAL);
72 pass_type_enum.insert("roughness", PASS_ROUGHNESS);
73 pass_type_enum.insert("uv", PASS_UV);
74 pass_type_enum.insert("object_id", PASS_OBJECT_ID);
75 pass_type_enum.insert("material_id", PASS_MATERIAL_ID);
76 pass_type_enum.insert("motion", PASS_MOTION);
77 pass_type_enum.insert("motion_weight", PASS_MOTION_WEIGHT);
78 pass_type_enum.insert("cryptomatte", PASS_CRYPTOMATTE);
79 pass_type_enum.insert("aov_color", PASS_AOV_COLOR);
80 pass_type_enum.insert("aov_value", PASS_AOV_VALUE);
81 pass_type_enum.insert("adaptive_aux_buffer", PASS_ADAPTIVE_AUX_BUFFER);
82 pass_type_enum.insert("sample_count", PASS_SAMPLE_COUNT);
83 pass_type_enum.insert("diffuse_color", PASS_DIFFUSE_COLOR);
84 pass_type_enum.insert("glossy_color", PASS_GLOSSY_COLOR);
85 pass_type_enum.insert("transmission_color", PASS_TRANSMISSION_COLOR);
86 pass_type_enum.insert("mist", PASS_MIST);
87 pass_type_enum.insert("denoising_normal", PASS_DENOISING_NORMAL);
88 pass_type_enum.insert("denoising_albedo", PASS_DENOISING_ALBEDO);
89 pass_type_enum.insert("denoising_depth", PASS_DENOISING_DEPTH);
90 pass_type_enum.insert("denoising_previous", PASS_DENOISING_PREVIOUS);
91
92 pass_type_enum.insert("shadow_catcher", PASS_SHADOW_CATCHER);
93 pass_type_enum.insert("shadow_catcher_sample_count", PASS_SHADOW_CATCHER_SAMPLE_COUNT);
94 pass_type_enum.insert("shadow_catcher_matte", PASS_SHADOW_CATCHER_MATTE);
95
96 pass_type_enum.insert("bake_primitive", PASS_BAKE_PRIMITIVE);
97 pass_type_enum.insert("bake_seed", PASS_BAKE_SEED);
98 pass_type_enum.insert("bake_differential", PASS_BAKE_DIFFERENTIAL);
99
100#ifdef WITH_CYCLES_DEBUG
101 pass_type_enum.insert("guiding_color", PASS_GUIDING_COLOR);
102 pass_type_enum.insert("guiding_probability", PASS_GUIDING_PROBABILITY);
103 pass_type_enum.insert("guiding_avg_roughness", PASS_GUIDING_AVG_ROUGHNESS);
104#endif
105 }
106
107 return &pass_type_enum;
108}
109
111{
112 static NodeEnum pass_mode_enum;
113
114 if (pass_mode_enum.empty()) {
115 pass_mode_enum.insert("noisy", static_cast<int>(PassMode::NOISY));
116 pass_mode_enum.insert("denoised", static_cast<int>(PassMode::DENOISED));
117 }
118
119 return &pass_mode_enum;
120}
121
123{
124 NodeType *type = NodeType::add("pass", create);
125
126 const NodeEnum *pass_type_enum = get_type_enum();
127 const NodeEnum *pass_mode_enum = get_mode_enum();
128
129 SOCKET_ENUM(type, "Type", *pass_type_enum, PASS_COMBINED);
130 SOCKET_ENUM(mode, "Mode", *pass_mode_enum, static_cast<int>(PassMode::DENOISED));
131 SOCKET_STRING(name, "Name", ustring());
132 SOCKET_BOOLEAN(include_albedo, "Include Albedo", false);
133 SOCKET_STRING(lightgroup, "Light Group", ustring());
134
135 return type;
136}
137
138Pass::Pass() : Node(get_node_type()), is_auto_(false) {}
139
141{
142 return get_info(type, include_albedo, !lightgroup.empty());
143}
144
146{
147 return get_info().is_written;
148}
149
150PassInfo Pass::get_info(const PassType type, const bool include_albedo, const bool is_lightgroup)
151{
152 PassInfo pass_info;
153
154 pass_info.use_filter = true;
155 pass_info.use_exposure = false;
156 pass_info.divide_type = PASS_NONE;
157 pass_info.use_compositing = false;
158 pass_info.use_denoising_albedo = true;
159
160 switch (type) {
161 case PASS_NONE:
162 pass_info.num_components = 0;
163 break;
164 case PASS_COMBINED:
165 pass_info.num_components = is_lightgroup ? 3 : 4;
166 pass_info.use_exposure = true;
167 pass_info.support_denoise = !is_lightgroup;
168 break;
169 case PASS_DEPTH:
170 pass_info.num_components = 1;
171 pass_info.use_filter = false;
172 break;
173 case PASS_MIST:
174 pass_info.num_components = 1;
175 break;
176 case PASS_POSITION:
177 pass_info.num_components = 3;
178 pass_info.use_filter = false;
179 break;
180 case PASS_NORMAL:
181 pass_info.num_components = 3;
182 break;
183 case PASS_ROUGHNESS:
184 pass_info.num_components = 1;
185 break;
186 case PASS_UV:
187 pass_info.num_components = 3;
188 break;
189 case PASS_MOTION:
190 pass_info.num_components = 4;
192 break;
194 pass_info.num_components = 1;
195 break;
196 case PASS_OBJECT_ID:
197 case PASS_MATERIAL_ID:
198 pass_info.num_components = 1;
199 pass_info.use_filter = false;
200 break;
201
202 case PASS_EMISSION:
203 case PASS_BACKGROUND:
204 pass_info.num_components = 3;
205 pass_info.use_exposure = true;
206 break;
207 case PASS_AO:
208 pass_info.num_components = 3;
209 break;
210
214 pass_info.num_components = 3;
215 break;
216 case PASS_DIFFUSE:
217 pass_info.num_components = 3;
218 pass_info.use_exposure = true;
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;
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;
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;
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;
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;
269 pass_info.use_compositing = true;
270 pass_info.is_written = false;
271 break;
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
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;
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
331 pass_info.num_components = 3;
332 pass_info.use_exposure = false;
333 pass_info.use_filter = false;
334 break;
335 case PASS_BAKE_SEED:
336 pass_info.num_components = 1;
337 pass_info.use_exposure = false;
338 pass_info.use_filter = false;
339 break;
341 pass_info.num_components = 4;
342 pass_info.use_exposure = false;
343 pass_info.use_filter = false;
344 break;
345
349 case PASS_NUM:
350 LOG(DFATAL) << "Unexpected pass type is used " << type;
351 pass_info.num_components = 0;
352 break;
354 pass_info.num_components = 3;
355 break;
357 pass_info.num_components = 1;
358 break;
360 pass_info.num_components = 1;
361 break;
362 }
363
364 return pass_info;
365}
366
368{
369 for (const Pass *pass : passes) {
370 if (pass->get_type() != type) {
371 continue;
372 }
373
374 return true;
375 }
376
377 return false;
378}
379
380const Pass *Pass::find(const unique_ptr_vector<Pass> &passes, const string &name)
381{
382 for (const Pass *pass : passes) {
383 if (pass->get_name() == name) {
384 return pass;
385 }
386 }
387
388 return nullptr;
389}
390
393 PassMode mode,
394 const ustring &lightgroup)
395{
396 for (const Pass *pass : passes) {
397 if (pass->get_type() != type || pass->get_mode() != mode ||
398 pass->get_lightgroup() != lightgroup)
399 {
400 continue;
401 }
402 return pass;
403 }
404
405 return nullptr;
406}
407
408int Pass::get_offset(const unique_ptr_vector<Pass> &passes, const Pass *pass)
409{
410 int pass_offset = 0;
411
412 for (const Pass *current_pass : passes) {
413 /* Note that pass name is allowed to be empty. This is why we check for type and mode. */
414 if (current_pass->get_type() == pass->get_type() &&
415 current_pass->get_mode() == pass->get_mode() &&
416 current_pass->get_name() == pass->get_name())
417 {
418 if (current_pass->is_written()) {
419 return pass_offset;
420 }
421 return PASS_UNUSED;
422 }
423 if (current_pass->is_written()) {
424 pass_offset += current_pass->get_info().num_components;
425 }
426 }
427
428 return PASS_UNUSED;
429}
430
431std::ostream &operator<<(std::ostream &os, const Pass &pass)
432{
433 os << "type: " << pass_type_as_string(pass.get_type());
434 os << ", name: \"" << pass.get_name() << "\"";
435 os << ", mode: " << pass.get_mode();
436 os << ", is_written: " << string_from_bool(pass.is_written());
437
438 return os;
439}
440
Definition pass.h:49
static const Pass * find(const unique_ptr_vector< Pass > &passes, const string &name)
Definition pass.cpp:380
PassInfo get_info() const
Definition pass.cpp:140
static int get_offset(const unique_ptr_vector< Pass > &passes, const Pass *pass)
Definition pass.cpp:408
static bool contains(const unique_ptr_vector< Pass > &passes, PassType type)
Definition pass.cpp:367
static const NodeEnum * get_type_enum()
Definition pass.cpp:44
NODE_DECLARE Pass()
Definition pass.cpp:138
bool is_written() const
Definition pass.cpp:145
static const NodeEnum * get_mode_enum()
Definition pass.cpp:110
bool is_auto_
Definition pass.h:71
#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_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:32
#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:25
CCL_NAMESPACE_BEGIN const char * pass_type_as_string(const PassType type)
Definition pass.cpp:11
std::ostream & operator<<(std::ostream &os, PassMode mode)
Definition pass.cpp:38
PassMode
Definition pass.h:20
@ DENOISED
Definition pass.h:22
@ NOISY
Definition pass.h:21
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: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