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