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