1 /*
2 * Copyright 2011-2013 Blender Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "device/device.h"
18
19 #include "render/background.h"
20 #include "render/camera.h"
21 #include "render/colorspace.h"
22 #include "render/graph.h"
23 #include "render/integrator.h"
24 #include "render/light.h"
25 #include "render/mesh.h"
26 #include "render/nodes.h"
27 #include "render/object.h"
28 #include "render/osl.h"
29 #include "render/scene.h"
30 #include "render/shader.h"
31 #include "render/svm.h"
32 #include "render/tables.h"
33
34 #include "util/util_foreach.h"
35 #include "util/util_murmurhash.h"
36 #include "util/util_task.h"
37
38 #ifdef WITH_OCIO
39 # include <OpenColorIO/OpenColorIO.h>
40 namespace OCIO = OCIO_NAMESPACE;
41 #endif
42
43 CCL_NAMESPACE_BEGIN
44
45 thread_mutex ShaderManager::lookup_table_mutex;
46 vector<float> ShaderManager::beckmann_table;
47 bool ShaderManager::beckmann_table_ready = false;
48
49 /* Beckmann sampling precomputed table, see bsdf_microfacet.h */
50
51 /* 2D slope distribution (alpha = 1.0) */
beckmann_table_P22(const float slope_x,const float slope_y)52 static float beckmann_table_P22(const float slope_x, const float slope_y)
53 {
54 return expf(-(slope_x * slope_x + slope_y * slope_y));
55 }
56
57 /* maximal slope amplitude (range that contains 99.99% of the distribution) */
beckmann_table_slope_max()58 static float beckmann_table_slope_max()
59 {
60 return 6.0;
61 }
62
63 /* MSVC 2015 needs this ugly hack to prevent a codegen bug on x86
64 * see T50176 for details
65 */
66 #if defined(_MSC_VER) && (_MSC_VER == 1900)
67 # define MSVC_VOLATILE volatile
68 #else
69 # define MSVC_VOLATILE
70 #endif
71
72 /* Paper used: Importance Sampling Microfacet-Based BSDFs with the
73 * Distribution of Visible Normals. Supplemental Material 2/2.
74 *
75 * http://hal.inria.fr/docs/01/00/66/20/ANNEX/supplemental2.pdf
76 */
beckmann_table_rows(float * table,int row_from,int row_to)77 static void beckmann_table_rows(float *table, int row_from, int row_to)
78 {
79 /* allocate temporary data */
80 const int DATA_TMP_SIZE = 512;
81 vector<double> slope_x(DATA_TMP_SIZE);
82 vector<double> CDF_P22_omega_i(DATA_TMP_SIZE);
83
84 /* loop over incident directions */
85 for (int index_theta = row_from; index_theta < row_to; index_theta++) {
86 /* incident vector */
87 const float cos_theta = index_theta / (BECKMANN_TABLE_SIZE - 1.0f);
88 const float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta);
89
90 /* for a given incident vector
91 * integrate P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
92 slope_x[0] = (double)-beckmann_table_slope_max();
93 CDF_P22_omega_i[0] = 0;
94
95 for (MSVC_VOLATILE int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x) {
96 /* slope_x */
97 slope_x[index_slope_x] = (double)(-beckmann_table_slope_max() +
98 2.0f * beckmann_table_slope_max() * index_slope_x /
99 (DATA_TMP_SIZE - 1.0f));
100
101 /* dot product with incident vector */
102 float dot_product = fmaxf(0.0f, -(float)slope_x[index_slope_x] * sin_theta + cos_theta);
103 /* marginalize P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
104 float P22_omega_i = 0.0f;
105
106 for (int j = 0; j < 100; ++j) {
107 float slope_y = -beckmann_table_slope_max() +
108 2.0f * beckmann_table_slope_max() * j * (1.0f / 99.0f);
109 P22_omega_i += dot_product * beckmann_table_P22((float)slope_x[index_slope_x], slope_y);
110 }
111
112 /* CDF of P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
113 CDF_P22_omega_i[index_slope_x] = CDF_P22_omega_i[index_slope_x - 1] + (double)P22_omega_i;
114 }
115
116 /* renormalize CDF_P22_omega_i */
117 for (int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x)
118 CDF_P22_omega_i[index_slope_x] /= CDF_P22_omega_i[DATA_TMP_SIZE - 1];
119
120 /* loop over random number U1 */
121 int index_slope_x = 0;
122
123 for (int index_U = 0; index_U < BECKMANN_TABLE_SIZE; ++index_U) {
124 const double U = 0.0000001 + 0.9999998 * index_U / (double)(BECKMANN_TABLE_SIZE - 1);
125
126 /* inverse CDF_P22_omega_i, solve Eq.(11) */
127 while (CDF_P22_omega_i[index_slope_x] <= U)
128 ++index_slope_x;
129
130 const double interp = (CDF_P22_omega_i[index_slope_x] - U) /
131 (CDF_P22_omega_i[index_slope_x] - CDF_P22_omega_i[index_slope_x - 1]);
132
133 /* store value */
134 table[index_U + index_theta * BECKMANN_TABLE_SIZE] =
135 (float)(interp * slope_x[index_slope_x - 1] + (1.0 - interp) * slope_x[index_slope_x]);
136 }
137 }
138 }
139
140 #undef MSVC_VOLATILE
141
beckmann_table_build(vector<float> & table)142 static void beckmann_table_build(vector<float> &table)
143 {
144 table.resize(BECKMANN_TABLE_SIZE * BECKMANN_TABLE_SIZE);
145
146 /* multithreaded build */
147 TaskPool pool;
148
149 for (int i = 0; i < BECKMANN_TABLE_SIZE; i += 8)
150 pool.push(function_bind(&beckmann_table_rows, &table[0], i, i + 8));
151
152 pool.wait_work();
153 }
154
155 /* Shader */
156
NODE_DEFINE(Shader)157 NODE_DEFINE(Shader)
158 {
159 NodeType *type = NodeType::add("shader", create);
160
161 SOCKET_BOOLEAN(use_mis, "Use MIS", true);
162 SOCKET_BOOLEAN(use_transparent_shadow, "Use Transparent Shadow", true);
163 SOCKET_BOOLEAN(heterogeneous_volume, "Heterogeneous Volume", true);
164
165 static NodeEnum volume_sampling_method_enum;
166 volume_sampling_method_enum.insert("distance", VOLUME_SAMPLING_DISTANCE);
167 volume_sampling_method_enum.insert("equiangular", VOLUME_SAMPLING_EQUIANGULAR);
168 volume_sampling_method_enum.insert("multiple_importance", VOLUME_SAMPLING_MULTIPLE_IMPORTANCE);
169 SOCKET_ENUM(volume_sampling_method,
170 "Volume Sampling Method",
171 volume_sampling_method_enum,
172 VOLUME_SAMPLING_MULTIPLE_IMPORTANCE);
173
174 static NodeEnum volume_interpolation_method_enum;
175 volume_interpolation_method_enum.insert("linear", VOLUME_INTERPOLATION_LINEAR);
176 volume_interpolation_method_enum.insert("cubic", VOLUME_INTERPOLATION_CUBIC);
177 SOCKET_ENUM(volume_interpolation_method,
178 "Volume Interpolation Method",
179 volume_interpolation_method_enum,
180 VOLUME_INTERPOLATION_LINEAR);
181
182 SOCKET_FLOAT(volume_step_rate, "Volume Step Rate", 1.0f);
183
184 static NodeEnum displacement_method_enum;
185 displacement_method_enum.insert("bump", DISPLACE_BUMP);
186 displacement_method_enum.insert("true", DISPLACE_TRUE);
187 displacement_method_enum.insert("both", DISPLACE_BOTH);
188 SOCKET_ENUM(displacement_method, "Displacement Method", displacement_method_enum, DISPLACE_BUMP);
189
190 return type;
191 }
192
Shader()193 Shader::Shader() : Node(node_type)
194 {
195 pass_id = 0;
196
197 graph = NULL;
198
199 has_surface = false;
200 has_surface_transparent = false;
201 has_surface_emission = false;
202 has_surface_bssrdf = false;
203 has_volume = false;
204 has_displacement = false;
205 has_bump = false;
206 has_bssrdf_bump = false;
207 has_surface_spatial_varying = false;
208 has_volume_spatial_varying = false;
209 has_volume_attribute_dependency = false;
210 has_integrator_dependency = false;
211 has_volume_connected = false;
212 prev_volume_step_rate = 0.0f;
213
214 displacement_method = DISPLACE_BUMP;
215
216 id = -1;
217 used = false;
218
219 need_update = true;
220 need_update_geometry = true;
221 }
222
~Shader()223 Shader::~Shader()
224 {
225 delete graph;
226 }
227
is_constant_emission(float3 * emission)228 bool Shader::is_constant_emission(float3 *emission)
229 {
230 /* If the shader has AOVs, they need to be evaluated, so we can't skip the shader. */
231 foreach (ShaderNode *node, graph->nodes) {
232 if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) {
233 return false;
234 }
235 }
236
237 ShaderInput *surf = graph->output()->input("Surface");
238
239 if (surf->link == NULL) {
240 return false;
241 }
242
243 if (surf->link->parent->type == EmissionNode::node_type) {
244 EmissionNode *node = (EmissionNode *)surf->link->parent;
245
246 assert(node->input("Color"));
247 assert(node->input("Strength"));
248
249 if (node->input("Color")->link || node->input("Strength")->link) {
250 return false;
251 }
252
253 *emission = node->color * node->strength;
254 }
255 else if (surf->link->parent->type == BackgroundNode::node_type) {
256 BackgroundNode *node = (BackgroundNode *)surf->link->parent;
257
258 assert(node->input("Color"));
259 assert(node->input("Strength"));
260
261 if (node->input("Color")->link || node->input("Strength")->link) {
262 return false;
263 }
264
265 *emission = node->color * node->strength;
266 }
267 else {
268 return false;
269 }
270
271 return true;
272 }
273
set_graph(ShaderGraph * graph_)274 void Shader::set_graph(ShaderGraph *graph_)
275 {
276 /* do this here already so that we can detect if mesh or object attributes
277 * are needed, since the node attribute callbacks check if their sockets
278 * are connected but proxy nodes should not count */
279 if (graph_) {
280 graph_->remove_proxy_nodes();
281
282 if (displacement_method != DISPLACE_BUMP) {
283 graph_->compute_displacement_hash();
284 }
285 }
286
287 /* update geometry if displacement changed */
288 if (displacement_method != DISPLACE_BUMP) {
289 const char *old_hash = (graph) ? graph->displacement_hash.c_str() : "";
290 const char *new_hash = (graph_) ? graph_->displacement_hash.c_str() : "";
291
292 if (strcmp(old_hash, new_hash) != 0) {
293 need_update_geometry = true;
294 }
295 }
296
297 /* assign graph */
298 delete graph;
299 graph = graph_;
300
301 /* Store info here before graph optimization to make sure that
302 * nodes that get optimized away still count. */
303 has_volume_connected = (graph->output()->input("Volume")->link != NULL);
304 }
305
tag_update(Scene * scene)306 void Shader::tag_update(Scene *scene)
307 {
308 /* update tag */
309 need_update = true;
310 scene->shader_manager->need_update = true;
311
312 /* if the shader previously was emissive, update light distribution,
313 * if the new shader is emissive, a light manager update tag will be
314 * done in the shader manager device update. */
315 if (use_mis && has_surface_emission)
316 scene->light_manager->need_update = true;
317
318 /* Special handle of background MIS light for now: for some reason it
319 * has use_mis set to false. We are quite close to release now, so
320 * better to be safe.
321 */
322 if (this == scene->background->get_shader(scene)) {
323 scene->light_manager->need_update_background = true;
324 if (scene->light_manager->has_background_light(scene)) {
325 scene->light_manager->need_update = true;
326 }
327 }
328
329 /* quick detection of which kind of shaders we have to avoid loading
330 * e.g. surface attributes when there is only a volume shader. this could
331 * be more fine grained but it's better than nothing */
332 OutputNode *output = graph->output();
333 bool prev_has_volume = has_volume;
334 has_surface = has_surface || output->input("Surface")->link;
335 has_volume = has_volume || output->input("Volume")->link;
336 has_displacement = has_displacement || output->input("Displacement")->link;
337
338 /* get requested attributes. this could be optimized by pruning unused
339 * nodes here already, but that's the job of the shader manager currently,
340 * and may not be so great for interactive rendering where you temporarily
341 * disconnect a node */
342
343 AttributeRequestSet prev_attributes = attributes;
344
345 attributes.clear();
346 foreach (ShaderNode *node, graph->nodes)
347 node->attributes(this, &attributes);
348
349 if (has_displacement && displacement_method == DISPLACE_BOTH) {
350 attributes.add(ATTR_STD_POSITION_UNDISPLACED);
351 }
352
353 /* compare if the attributes changed, mesh manager will check
354 * need_update_geometry, update the relevant meshes and clear it. */
355 if (attributes.modified(prev_attributes)) {
356 need_update_geometry = true;
357 scene->geometry_manager->need_update = true;
358 }
359
360 if (has_volume != prev_has_volume || volume_step_rate != prev_volume_step_rate) {
361 scene->geometry_manager->need_flags_update = true;
362 scene->object_manager->need_flags_update = true;
363 prev_volume_step_rate = volume_step_rate;
364 }
365 }
366
tag_used(Scene * scene)367 void Shader::tag_used(Scene *scene)
368 {
369 /* if an unused shader suddenly gets used somewhere, it needs to be
370 * recompiled because it was skipped for compilation before */
371 if (!used) {
372 need_update = true;
373 scene->shader_manager->need_update = true;
374 }
375 }
376
377 /* Shader Manager */
378
ShaderManager()379 ShaderManager::ShaderManager()
380 {
381 need_update = true;
382 beckmann_table_offset = TABLE_OFFSET_INVALID;
383
384 xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f);
385 xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f);
386 xyz_to_b = make_float3(0.0556434f, -0.2040259f, 1.0572252f);
387 rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f);
388
389 #ifdef WITH_OCIO
390 OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
391 if (config) {
392 if (config->hasRole("XYZ") && config->hasRole("scene_linear")) {
393 OCIO::ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear");
394 OCIO::ConstProcessorRcPtr to_xyz_processor = config->getProcessor("scene_linear", "XYZ");
395 if (to_rgb_processor && to_xyz_processor) {
396 float r[] = {1.0f, 0.0f, 0.0f};
397 float g[] = {0.0f, 1.0f, 0.0f};
398 float b[] = {0.0f, 0.0f, 1.0f};
399 to_xyz_processor->applyRGB(r);
400 to_xyz_processor->applyRGB(g);
401 to_xyz_processor->applyRGB(b);
402 rgb_to_y = make_float3(r[1], g[1], b[1]);
403
404 float x[] = {1.0f, 0.0f, 0.0f};
405 float y[] = {0.0f, 1.0f, 0.0f};
406 float z[] = {0.0f, 0.0f, 1.0f};
407 to_rgb_processor->applyRGB(x);
408 to_rgb_processor->applyRGB(y);
409 to_rgb_processor->applyRGB(z);
410 xyz_to_r = make_float3(x[0], y[0], z[0]);
411 xyz_to_g = make_float3(x[1], y[1], z[1]);
412 xyz_to_b = make_float3(x[2], y[2], z[2]);
413 }
414 }
415 }
416 #endif
417 }
418
~ShaderManager()419 ShaderManager::~ShaderManager()
420 {
421 }
422
create(int shadingsystem)423 ShaderManager *ShaderManager::create(int shadingsystem)
424 {
425 ShaderManager *manager;
426
427 (void)shadingsystem; /* Ignored when built without OSL. */
428
429 #ifdef WITH_OSL
430 if (shadingsystem == SHADINGSYSTEM_OSL) {
431 manager = new OSLShaderManager();
432 }
433 else
434 #endif
435 {
436 manager = new SVMShaderManager();
437 }
438
439 return manager;
440 }
441
get_attribute_id(ustring name)442 uint ShaderManager::get_attribute_id(ustring name)
443 {
444 thread_scoped_spin_lock lock(attribute_lock_);
445
446 /* get a unique id for each name, for SVM attribute lookup */
447 AttributeIDMap::iterator it = unique_attribute_id.find(name);
448
449 if (it != unique_attribute_id.end())
450 return it->second;
451
452 uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
453 unique_attribute_id[name] = id;
454 return id;
455 }
456
get_attribute_id(AttributeStandard std)457 uint ShaderManager::get_attribute_id(AttributeStandard std)
458 {
459 return (uint)std;
460 }
461
get_shader_id(Shader * shader,bool smooth)462 int ShaderManager::get_shader_id(Shader *shader, bool smooth)
463 {
464 /* get a shader id to pass to the kernel */
465 int id = shader->id;
466
467 /* smooth flag */
468 if (smooth)
469 id |= SHADER_SMOOTH_NORMAL;
470
471 /* default flags */
472 id |= SHADER_CAST_SHADOW | SHADER_AREA_LIGHT;
473
474 return id;
475 }
476
update_shaders_used(Scene * scene)477 void ShaderManager::update_shaders_used(Scene *scene)
478 {
479 if (!need_update) {
480 return;
481 }
482
483 /* figure out which shaders are in use, so SVM/OSL can skip compiling them
484 * for speed and avoid loading image textures into memory */
485 uint id = 0;
486 foreach (Shader *shader, scene->shaders) {
487 shader->used = false;
488 shader->id = id++;
489 }
490
491 scene->default_surface->used = true;
492 scene->default_light->used = true;
493 scene->default_background->used = true;
494 scene->default_empty->used = true;
495
496 if (scene->background->shader)
497 scene->background->shader->used = true;
498
499 foreach (Geometry *geom, scene->geometry)
500 foreach (Shader *shader, geom->used_shaders)
501 shader->used = true;
502
503 foreach (Light *light, scene->lights)
504 if (light->shader)
505 light->shader->used = true;
506 }
507
device_update_common(Device * device,DeviceScene * dscene,Scene * scene,Progress &)508 void ShaderManager::device_update_common(Device *device,
509 DeviceScene *dscene,
510 Scene *scene,
511 Progress & /*progress*/)
512 {
513 dscene->shaders.free();
514
515 if (scene->shaders.size() == 0)
516 return;
517
518 KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size());
519 bool has_volumes = false;
520 bool has_transparent_shadow = false;
521
522 foreach (Shader *shader, scene->shaders) {
523 uint flag = 0;
524
525 if (shader->use_mis)
526 flag |= SD_USE_MIS;
527 if (shader->has_surface_transparent && shader->use_transparent_shadow)
528 flag |= SD_HAS_TRANSPARENT_SHADOW;
529 if (shader->has_volume) {
530 flag |= SD_HAS_VOLUME;
531 has_volumes = true;
532
533 /* todo: this could check more fine grained, to skip useless volumes
534 * enclosed inside an opaque bsdf.
535 */
536 flag |= SD_HAS_TRANSPARENT_SHADOW;
537 }
538 /* in this case we can assume transparent surface */
539 if (shader->has_volume_connected && !shader->has_surface)
540 flag |= SD_HAS_ONLY_VOLUME;
541 if (shader->has_volume) {
542 if (shader->heterogeneous_volume && shader->has_volume_spatial_varying)
543 flag |= SD_HETEROGENEOUS_VOLUME;
544 }
545 if (shader->has_volume_attribute_dependency)
546 flag |= SD_NEED_VOLUME_ATTRIBUTES;
547 if (shader->has_bssrdf_bump)
548 flag |= SD_HAS_BSSRDF_BUMP;
549 if (device->info.has_volume_decoupled) {
550 if (shader->volume_sampling_method == VOLUME_SAMPLING_EQUIANGULAR)
551 flag |= SD_VOLUME_EQUIANGULAR;
552 if (shader->volume_sampling_method == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE)
553 flag |= SD_VOLUME_MIS;
554 }
555 if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC)
556 flag |= SD_VOLUME_CUBIC;
557 if (shader->has_bump)
558 flag |= SD_HAS_BUMP;
559 if (shader->displacement_method != DISPLACE_BUMP)
560 flag |= SD_HAS_DISPLACEMENT;
561
562 /* constant emission check */
563 float3 constant_emission = make_float3(0.0f, 0.0f, 0.0f);
564 if (shader->is_constant_emission(&constant_emission))
565 flag |= SD_HAS_CONSTANT_EMISSION;
566
567 uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
568
569 /* regular shader */
570 kshader->flags = flag;
571 kshader->pass_id = shader->pass_id;
572 kshader->constant_emission[0] = constant_emission.x;
573 kshader->constant_emission[1] = constant_emission.y;
574 kshader->constant_emission[2] = constant_emission.z;
575 kshader->cryptomatte_id = util_hash_to_float(cryptomatte_id);
576 kshader++;
577
578 has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
579 }
580
581 dscene->shaders.copy_to_device();
582
583 /* lookup tables */
584 KernelTables *ktables = &dscene->data.tables;
585
586 /* beckmann lookup table */
587 if (beckmann_table_offset == TABLE_OFFSET_INVALID) {
588 if (!beckmann_table_ready) {
589 thread_scoped_lock lock(lookup_table_mutex);
590 if (!beckmann_table_ready) {
591 beckmann_table_build(beckmann_table);
592 beckmann_table_ready = true;
593 }
594 }
595 beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table);
596 }
597 ktables->beckmann_offset = (int)beckmann_table_offset;
598
599 /* integrator */
600 KernelIntegrator *kintegrator = &dscene->data.integrator;
601 kintegrator->use_volumes = has_volumes;
602 /* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
603 kintegrator->transparent_shadows = has_transparent_shadow;
604
605 /* film */
606 KernelFilm *kfilm = &dscene->data.film;
607 /* color space, needs to be here because e.g. displacement shaders could depend on it */
608 kfilm->xyz_to_r = float3_to_float4(xyz_to_r);
609 kfilm->xyz_to_g = float3_to_float4(xyz_to_g);
610 kfilm->xyz_to_b = float3_to_float4(xyz_to_b);
611 kfilm->rgb_to_y = float3_to_float4(rgb_to_y);
612 }
613
device_free_common(Device *,DeviceScene * dscene,Scene * scene)614 void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
615 {
616 scene->lookup_tables->remove_table(&beckmann_table_offset);
617
618 dscene->shaders.free();
619 }
620
add_default(Scene * scene)621 void ShaderManager::add_default(Scene *scene)
622 {
623 /* default surface */
624 {
625 ShaderGraph *graph = new ShaderGraph();
626
627 DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
628 diffuse->color = make_float3(0.8f, 0.8f, 0.8f);
629 graph->add(diffuse);
630
631 graph->connect(diffuse->output("BSDF"), graph->output()->input("Surface"));
632
633 Shader *shader = scene->create_node<Shader>();
634 shader->name = "default_surface";
635 shader->set_graph(graph);
636 scene->default_surface = shader;
637 shader->tag_update(scene);
638 }
639
640 /* default volume */
641 {
642 ShaderGraph *graph = new ShaderGraph();
643
644 PrincipledVolumeNode *principled = graph->create_node<PrincipledVolumeNode>();
645 graph->add(principled);
646
647 graph->connect(principled->output("Volume"), graph->output()->input("Volume"));
648
649 Shader *shader = scene->create_node<Shader>();
650 shader->name = "default_volume";
651 shader->set_graph(graph);
652 scene->default_volume = shader;
653 shader->tag_update(scene);
654 }
655
656 /* default light */
657 {
658 ShaderGraph *graph = new ShaderGraph();
659
660 EmissionNode *emission = graph->create_node<EmissionNode>();
661 emission->color = make_float3(0.8f, 0.8f, 0.8f);
662 emission->strength = 0.0f;
663 graph->add(emission);
664
665 graph->connect(emission->output("Emission"), graph->output()->input("Surface"));
666
667 Shader *shader = scene->create_node<Shader>();
668 shader->name = "default_light";
669 shader->set_graph(graph);
670 scene->default_light = shader;
671 shader->tag_update(scene);
672 }
673
674 /* default background */
675 {
676 ShaderGraph *graph = new ShaderGraph();
677
678 Shader *shader = scene->create_node<Shader>();
679 shader->name = "default_background";
680 shader->set_graph(graph);
681 scene->default_background = shader;
682 shader->tag_update(scene);
683 }
684
685 /* default empty */
686 {
687 ShaderGraph *graph = new ShaderGraph();
688
689 Shader *shader = scene->create_node<Shader>();
690 shader->name = "default_empty";
691 shader->set_graph(graph);
692 scene->default_empty = shader;
693 shader->tag_update(scene);
694 }
695 }
696
get_requested_graph_features(ShaderGraph * graph,DeviceRequestedFeatures * requested_features)697 void ShaderManager::get_requested_graph_features(ShaderGraph *graph,
698 DeviceRequestedFeatures *requested_features)
699 {
700 foreach (ShaderNode *node, graph->nodes) {
701 requested_features->max_nodes_group = max(requested_features->max_nodes_group,
702 node->get_group());
703 requested_features->nodes_features |= node->get_feature();
704 if (node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) {
705 BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode *>(node);
706 if (CLOSURE_IS_VOLUME(bsdf_node->closure)) {
707 requested_features->nodes_features |= NODE_FEATURE_VOLUME;
708 }
709 else if (CLOSURE_IS_PRINCIPLED(bsdf_node->closure)) {
710 requested_features->use_principled = true;
711 }
712 }
713 if (node->has_surface_bssrdf()) {
714 requested_features->use_subsurface = true;
715 }
716 if (node->has_surface_transparent()) {
717 requested_features->use_transparent = true;
718 }
719 if (node->has_raytrace()) {
720 requested_features->use_shader_raytrace = true;
721 }
722 }
723 }
724
get_requested_features(Scene * scene,DeviceRequestedFeatures * requested_features)725 void ShaderManager::get_requested_features(Scene *scene,
726 DeviceRequestedFeatures *requested_features)
727 {
728 requested_features->max_nodes_group = NODE_GROUP_LEVEL_0;
729 requested_features->nodes_features = 0;
730 for (int i = 0; i < scene->shaders.size(); i++) {
731 Shader *shader = scene->shaders[i];
732 if (!shader->used) {
733 continue;
734 }
735
736 /* Gather requested features from all the nodes from the graph nodes. */
737 get_requested_graph_features(shader->graph, requested_features);
738 ShaderNode *output_node = shader->graph->output();
739 if (output_node->input("Displacement")->link != NULL) {
740 requested_features->nodes_features |= NODE_FEATURE_BUMP;
741 if (shader->displacement_method == DISPLACE_BOTH) {
742 requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE;
743 requested_features->max_nodes_group = max(requested_features->max_nodes_group,
744 NODE_GROUP_LEVEL_1);
745 }
746 }
747 /* On top of volume nodes, also check if we need volume sampling because
748 * e.g. an Emission node would slip through the NODE_FEATURE_VOLUME check */
749 if (shader->has_volume)
750 requested_features->use_volume |= true;
751 }
752 }
753
free_memory()754 void ShaderManager::free_memory()
755 {
756 beckmann_table.free_memory();
757
758 #ifdef WITH_OSL
759 OSLShaderManager::free_memory();
760 #endif
761
762 ColorSpaceManager::free_memory();
763 }
764
linear_rgb_to_gray(float3 c)765 float ShaderManager::linear_rgb_to_gray(float3 c)
766 {
767 return dot(c, rgb_to_y);
768 }
769
get_cryptomatte_materials(Scene * scene)770 string ShaderManager::get_cryptomatte_materials(Scene *scene)
771 {
772 string manifest = "{";
773 unordered_set<ustring, ustringHash> materials;
774 foreach (Shader *shader, scene->shaders) {
775 if (materials.count(shader->name)) {
776 continue;
777 }
778 materials.insert(shader->name);
779 uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
780 manifest += string_printf("\"%s\":\"%08x\",", shader->name.c_str(), cryptomatte_id);
781 }
782 manifest[manifest.size() - 1] = '}';
783 return manifest;
784 }
785
786 CCL_NAMESPACE_END
787