Blender  V2.93
shader.cpp
Go to the documentation of this file.
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/alembic.h"
20 #include "render/background.h"
21 #include "render/camera.h"
22 #include "render/colorspace.h"
23 #include "render/graph.h"
24 #include "render/integrator.h"
25 #include "render/light.h"
26 #include "render/mesh.h"
27 #include "render/nodes.h"
28 #include "render/object.h"
29 #include "render/osl.h"
30 #include "render/scene.h"
31 #include "render/shader.h"
32 #include "render/svm.h"
33 #include "render/tables.h"
34 
35 #include "util/util_foreach.h"
36 #include "util/util_murmurhash.h"
37 #include "util/util_task.h"
38 #include "util/util_transform.h"
39 
40 #ifdef WITH_OCIO
41 # include <OpenColorIO/OpenColorIO.h>
42 namespace OCIO = OCIO_NAMESPACE;
43 #endif
44 
46 
50 
51 /* Beckmann sampling precomputed table, see bsdf_microfacet.h */
52 
53 /* 2D slope distribution (alpha = 1.0) */
54 static float beckmann_table_P22(const float slope_x, const float slope_y)
55 {
56  return expf(-(slope_x * slope_x + slope_y * slope_y));
57 }
58 
59 /* maximal slope amplitude (range that contains 99.99% of the distribution) */
61 {
62  return 6.0;
63 }
64 
65 /* MSVC 2015 needs this ugly hack to prevent a codegen bug on x86
66  * see T50176 for details
67  */
68 #if defined(_MSC_VER) && (_MSC_VER == 1900)
69 # define MSVC_VOLATILE volatile
70 #else
71 # define MSVC_VOLATILE
72 #endif
73 
74 /* Paper used: Importance Sampling Microfacet-Based BSDFs with the
75  * Distribution of Visible Normals. Supplemental Material 2/2.
76  *
77  * http://hal.inria.fr/docs/01/00/66/20/ANNEX/supplemental2.pdf
78  */
79 static void beckmann_table_rows(float *table, int row_from, int row_to)
80 {
81  /* allocate temporary data */
82  const int DATA_TMP_SIZE = 512;
83  vector<double> slope_x(DATA_TMP_SIZE);
84  vector<double> CDF_P22_omega_i(DATA_TMP_SIZE);
85 
86  /* loop over incident directions */
87  for (int index_theta = row_from; index_theta < row_to; index_theta++) {
88  /* incident vector */
89  const float cos_theta = index_theta / (BECKMANN_TABLE_SIZE - 1.0f);
90  const float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta);
91 
92  /* for a given incident vector
93  * integrate P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
94  slope_x[0] = (double)-beckmann_table_slope_max();
95  CDF_P22_omega_i[0] = 0;
96 
97  for (MSVC_VOLATILE int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x) {
98  /* slope_x */
99  slope_x[index_slope_x] = (double)(-beckmann_table_slope_max() +
100  2.0f * beckmann_table_slope_max() * index_slope_x /
101  (DATA_TMP_SIZE - 1.0f));
102 
103  /* dot product with incident vector */
104  float dot_product = fmaxf(0.0f, -(float)slope_x[index_slope_x] * sin_theta + cos_theta);
105  /* marginalize P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
106  float P22_omega_i = 0.0f;
107 
108  for (int j = 0; j < 100; ++j) {
109  float slope_y = -beckmann_table_slope_max() +
110  2.0f * beckmann_table_slope_max() * j * (1.0f / 99.0f);
111  P22_omega_i += dot_product * beckmann_table_P22((float)slope_x[index_slope_x], slope_y);
112  }
113 
114  /* CDF of P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
115  CDF_P22_omega_i[index_slope_x] = CDF_P22_omega_i[index_slope_x - 1] + (double)P22_omega_i;
116  }
117 
118  /* renormalize CDF_P22_omega_i */
119  for (int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x)
120  CDF_P22_omega_i[index_slope_x] /= CDF_P22_omega_i[DATA_TMP_SIZE - 1];
121 
122  /* loop over random number U1 */
123  int index_slope_x = 0;
124 
125  for (int index_U = 0; index_U < BECKMANN_TABLE_SIZE; ++index_U) {
126  const double U = 0.0000001 + 0.9999998 * index_U / (double)(BECKMANN_TABLE_SIZE - 1);
127 
128  /* inverse CDF_P22_omega_i, solve Eq.(11) */
129  while (CDF_P22_omega_i[index_slope_x] <= U)
130  ++index_slope_x;
131 
132  const double interp = (CDF_P22_omega_i[index_slope_x] - U) /
133  (CDF_P22_omega_i[index_slope_x] - CDF_P22_omega_i[index_slope_x - 1]);
134 
135  /* store value */
136  table[index_U + index_theta * BECKMANN_TABLE_SIZE] =
137  (float)(interp * slope_x[index_slope_x - 1] + (1.0 - interp) * slope_x[index_slope_x]);
138  }
139  }
140 }
141 
142 #undef MSVC_VOLATILE
143 
145 {
147 
148  /* multithreaded build */
149  TaskPool pool;
150 
151  for (int i = 0; i < BECKMANN_TABLE_SIZE; i += 8)
152  pool.push(function_bind(&beckmann_table_rows, &table[0], i, i + 8));
153 
154  pool.wait_work();
155 }
156 
157 /* Shader */
158 
160 {
161  NodeType *type = NodeType::add("shader", create);
162 
163  SOCKET_BOOLEAN(use_mis, "Use MIS", true);
164  SOCKET_BOOLEAN(use_transparent_shadow, "Use Transparent Shadow", true);
165  SOCKET_BOOLEAN(heterogeneous_volume, "Heterogeneous Volume", true);
166 
167  static NodeEnum volume_sampling_method_enum;
168  volume_sampling_method_enum.insert("distance", VOLUME_SAMPLING_DISTANCE);
169  volume_sampling_method_enum.insert("equiangular", VOLUME_SAMPLING_EQUIANGULAR);
170  volume_sampling_method_enum.insert("multiple_importance", VOLUME_SAMPLING_MULTIPLE_IMPORTANCE);
171  SOCKET_ENUM(volume_sampling_method,
172  "Volume Sampling Method",
173  volume_sampling_method_enum,
175 
176  static NodeEnum volume_interpolation_method_enum;
177  volume_interpolation_method_enum.insert("linear", VOLUME_INTERPOLATION_LINEAR);
178  volume_interpolation_method_enum.insert("cubic", VOLUME_INTERPOLATION_CUBIC);
179  SOCKET_ENUM(volume_interpolation_method,
180  "Volume Interpolation Method",
181  volume_interpolation_method_enum,
183 
184  SOCKET_FLOAT(volume_step_rate, "Volume Step Rate", 1.0f);
185 
186  static NodeEnum displacement_method_enum;
187  displacement_method_enum.insert("bump", DISPLACE_BUMP);
188  displacement_method_enum.insert("true", DISPLACE_TRUE);
189  displacement_method_enum.insert("both", DISPLACE_BOTH);
190  SOCKET_ENUM(displacement_method, "Displacement Method", displacement_method_enum, DISPLACE_BUMP);
191 
192  SOCKET_INT(pass_id, "Pass ID", 0);
193 
194  return type;
195 }
196 
197 Shader::Shader() : Node(get_node_type())
198 {
199  pass_id = 0;
200 
201  graph = NULL;
202 
203  has_surface = false;
204  has_surface_transparent = false;
205  has_surface_emission = false;
206  has_surface_bssrdf = false;
207  has_volume = false;
208  has_displacement = false;
209  has_bump = false;
210  has_bssrdf_bump = false;
215  has_volume_connected = false;
216  prev_volume_step_rate = 0.0f;
217 
218  displacement_method = DISPLACE_BUMP;
219 
220  id = -1;
221  used = false;
222 
223  need_update_uvs = true;
224  need_update_attribute = true;
226 }
227 
229 {
230  delete graph;
231 }
232 
234 {
235  /* If the shader has AOVs, they need to be evaluated, so we can't skip the shader. */
236  foreach (ShaderNode *node, graph->nodes) {
237  if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) {
238  return false;
239  }
240  }
241 
242  ShaderInput *surf = graph->output()->input("Surface");
243 
244  if (surf->link == NULL) {
245  return false;
246  }
247 
248  if (surf->link->parent->type == EmissionNode::get_node_type()) {
250 
251  assert(node->input("Color"));
252  assert(node->input("Strength"));
253 
254  if (node->input("Color")->link || node->input("Strength")->link) {
255  return false;
256  }
257 
258  *emission = node->get_color() * node->get_strength();
259  }
260  else if (surf->link->parent->type == BackgroundNode::get_node_type()) {
262 
263  assert(node->input("Color"));
264  assert(node->input("Strength"));
265 
266  if (node->input("Color")->link || node->input("Strength")->link) {
267  return false;
268  }
269 
270  *emission = node->get_color() * node->get_strength();
271  }
272  else {
273  return false;
274  }
275 
276  return true;
277 }
278 
280 {
281  /* do this here already so that we can detect if mesh or object attributes
282  * are needed, since the node attribute callbacks check if their sockets
283  * are connected but proxy nodes should not count */
284  if (graph_) {
285  graph_->remove_proxy_nodes();
286 
287  if (displacement_method != DISPLACE_BUMP) {
288  graph_->compute_displacement_hash();
289  }
290  }
291 
292  /* update geometry if displacement changed */
293  if (displacement_method != DISPLACE_BUMP) {
294  const char *old_hash = (graph) ? graph->displacement_hash.c_str() : "";
295  const char *new_hash = (graph_) ? graph_->displacement_hash.c_str() : "";
296 
297  if (strcmp(old_hash, new_hash) != 0) {
299  }
300  }
301 
302  /* assign graph */
303  delete graph;
304  graph = graph_;
305 
306  /* Store info here before graph optimization to make sure that
307  * nodes that get optimized away still count. */
308  has_volume_connected = (graph->output()->input("Volume")->link != NULL);
309 }
310 
312 {
313  /* update tag */
314  tag_modified();
315 
317 
318  /* if the shader previously was emissive, update light distribution,
319  * if the new shader is emissive, a light manager update tag will be
320  * done in the shader manager device update. */
321  if (use_mis && has_surface_emission)
323 
324  /* Special handle of background MIS light for now: for some reason it
325  * has use_mis set to false. We are quite close to release now, so
326  * better to be safe.
327  */
328  if (this == scene->background->get_shader(scene)) {
332  }
333  }
334 
335  /* quick detection of which kind of shaders we have to avoid loading
336  * e.g. surface attributes when there is only a volume shader. this could
337  * be more fine grained but it's better than nothing */
339  bool prev_has_volume = has_volume;
340  has_surface = has_surface || output->input("Surface")->link;
341  has_volume = has_volume || output->input("Volume")->link;
342  has_displacement = has_displacement || output->input("Displacement")->link;
343 
344  /* get requested attributes. this could be optimized by pruning unused
345  * nodes here already, but that's the job of the shader manager currently,
346  * and may not be so great for interactive rendering where you temporarily
347  * disconnect a node */
348 
349  AttributeRequestSet prev_attributes = attributes;
350 
351  attributes.clear();
352  foreach (ShaderNode *node, graph->nodes)
353  node->attributes(this, &attributes);
354 
355  if (has_displacement) {
356  if (displacement_method == DISPLACE_BOTH) {
358  }
359  if (displacement_method_is_modified()) {
363  }
364  }
365 
366  /* compare if the attributes changed, mesh manager will check
367  * need_update_attribute, update the relevant meshes and clear it. */
368  if (attributes.modified(prev_attributes)) {
369  need_update_attribute = true;
372  }
373 
374  if (has_volume != prev_has_volume || volume_step_rate != prev_volume_step_rate) {
377  prev_volume_step_rate = volume_step_rate;
378  }
379 }
380 
382 {
383  /* if an unused shader suddenly gets used somewhere, it needs to be
384  * recompiled because it was skipped for compilation before */
385  if (!used) {
386  tag_modified();
388  }
389 }
390 
392 {
394 }
395 
396 /* Shader Manager */
397 
399 {
402 
404 }
405 
407 {
408 }
409 
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  return manager;
427 }
428 
430 {
432 
433  /* get a unique id for each name, for SVM attribute lookup */
434  AttributeIDMap::iterator it = unique_attribute_id.find(name);
435 
436  if (it != unique_attribute_id.end())
437  return it->second;
438 
439  uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
440  unique_attribute_id[name] = id;
441  return id;
442 }
443 
445 {
446  return (uint)std;
447 }
448 
450 {
451  /* get a shader id to pass to the kernel */
452  int id = shader->id;
453 
454  /* smooth flag */
455  if (smooth)
456  id |= SHADER_SMOOTH_NORMAL;
457 
458  /* default flags */
460 
461  return id;
462 }
463 
465 {
466  if (!need_update()) {
467  return;
468  }
469 
470  /* figure out which shaders are in use, so SVM/OSL can skip compiling them
471  * for speed and avoid loading image textures into memory */
472  uint id = 0;
473  foreach (Shader *shader, scene->shaders) {
474  shader->used = false;
475  shader->id = id++;
476  }
477 
478  scene->default_surface->used = true;
479  scene->default_light->used = true;
480  scene->default_background->used = true;
481  scene->default_empty->used = true;
482 
483  if (scene->background->get_shader())
484  scene->background->get_shader()->used = true;
485 
486 #ifdef WITH_ALEMBIC
487  foreach (Procedural *procedural, scene->procedurals) {
488  AlembicProcedural *abc_proc = static_cast<AlembicProcedural *>(procedural);
489 
490  foreach (Node *abc_node, abc_proc->get_objects()) {
491  AlembicObject *abc_object = static_cast<AlembicObject *>(abc_node);
492 
493  foreach (Node *node, abc_object->get_used_shaders()) {
494  Shader *shader = static_cast<Shader *>(node);
495  shader->used = true;
496  }
497  }
498  }
499 #endif
500 
501  foreach (Geometry *geom, scene->geometry)
502  foreach (Node *node, geom->get_used_shaders()) {
503  Shader *shader = static_cast<Shader *>(node);
504  shader->used = true;
505  }
506 
507  foreach (Light *light, scene->lights)
508  if (light->get_shader())
509  const_cast<Shader *>(light->get_shader())->used = true;
510 }
511 
513  DeviceScene *dscene,
514  Scene *scene,
515  Progress & /*progress*/)
516 {
517  dscene->shaders.free();
518 
519  if (scene->shaders.size() == 0)
520  return;
521 
522  KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size());
523  bool has_volumes = false;
524  bool has_transparent_shadow = false;
525 
526  foreach (Shader *shader, scene->shaders) {
527  uint flag = 0;
528 
529  if (shader->get_use_mis())
530  flag |= SD_USE_MIS;
531  if (shader->has_surface_transparent && shader->get_use_transparent_shadow())
533  if (shader->has_volume) {
534  flag |= SD_HAS_VOLUME;
535  has_volumes = true;
536 
537  /* todo: this could check more fine grained, to skip useless volumes
538  * enclosed inside an opaque bsdf.
539  */
541  }
542  /* in this case we can assume transparent surface */
543  if (shader->has_volume_connected && !shader->has_surface)
544  flag |= SD_HAS_ONLY_VOLUME;
545  if (shader->has_volume) {
546  if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying)
547  flag |= SD_HETEROGENEOUS_VOLUME;
548  }
549  if (shader->has_volume_attribute_dependency)
551  if (shader->has_bssrdf_bump)
552  flag |= SD_HAS_BSSRDF_BUMP;
553  if (device->info.has_volume_decoupled) {
554  if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_EQUIANGULAR)
555  flag |= SD_VOLUME_EQUIANGULAR;
556  if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE)
557  flag |= SD_VOLUME_MIS;
558  }
559  if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC)
560  flag |= SD_VOLUME_CUBIC;
561  if (shader->has_bump)
562  flag |= SD_HAS_BUMP;
563  if (shader->get_displacement_method() != DISPLACE_BUMP)
564  flag |= SD_HAS_DISPLACEMENT;
565 
566  /* constant emission check */
567  float3 constant_emission = zero_float3();
568  if (shader->is_constant_emission(&constant_emission))
569  flag |= SD_HAS_CONSTANT_EMISSION;
570 
571  uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
572 
573  /* regular shader */
574  kshader->flags = flag;
575  kshader->pass_id = shader->get_pass_id();
576  kshader->constant_emission[0] = constant_emission.x;
577  kshader->constant_emission[1] = constant_emission.y;
578  kshader->constant_emission[2] = constant_emission.z;
579  kshader->cryptomatte_id = util_hash_to_float(cryptomatte_id);
580  kshader++;
581 
582  has_transparent_shadow |= (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
583  }
584 
585  dscene->shaders.copy_to_device();
586 
587  /* lookup tables */
588  KernelTables *ktables = &dscene->data.tables;
589 
590  /* beckmann lookup table */
592  if (!beckmann_table_ready) {
594  if (!beckmann_table_ready) {
596  beckmann_table_ready = true;
597  }
598  }
600  }
601  ktables->beckmann_offset = (int)beckmann_table_offset;
602 
603  /* integrator */
604  KernelIntegrator *kintegrator = &dscene->data.integrator;
605  kintegrator->use_volumes = has_volumes;
606  /* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
607  kintegrator->transparent_shadows = has_transparent_shadow;
608 
609  /* film */
610  KernelFilm *kfilm = &dscene->data.film;
611  /* color space, needs to be here because e.g. displacement shaders could depend on it */
616 }
617 
619 {
621 
622  dscene->shaders.free();
623 }
624 
626 {
627  /* default surface */
628  {
629  ShaderGraph *graph = new ShaderGraph();
630 
631  DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
632  diffuse->set_color(make_float3(0.8f, 0.8f, 0.8f));
633  graph->add(diffuse);
634 
635  graph->connect(diffuse->output("BSDF"), graph->output()->input("Surface"));
636 
638  shader->name = "default_surface";
639  shader->set_graph(graph);
641  shader->tag_update(scene);
642  }
643 
644  /* default volume */
645  {
646  ShaderGraph *graph = new ShaderGraph();
647 
648  PrincipledVolumeNode *principled = graph->create_node<PrincipledVolumeNode>();
649  graph->add(principled);
650 
651  graph->connect(principled->output("Volume"), graph->output()->input("Volume"));
652 
654  shader->name = "default_volume";
655  shader->set_graph(graph);
657  shader->tag_update(scene);
658  }
659 
660  /* default light */
661  {
662  ShaderGraph *graph = new ShaderGraph();
663 
664  EmissionNode *emission = graph->create_node<EmissionNode>();
665  emission->set_color(make_float3(0.8f, 0.8f, 0.8f));
666  emission->set_strength(0.0f);
667  graph->add(emission);
668 
669  graph->connect(emission->output("Emission"), graph->output()->input("Surface"));
670 
672  shader->name = "default_light";
673  shader->set_graph(graph);
675  shader->tag_update(scene);
676  }
677 
678  /* default background */
679  {
680  ShaderGraph *graph = new ShaderGraph();
681 
683  shader->name = "default_background";
684  shader->set_graph(graph);
686  shader->tag_update(scene);
687  }
688 
689  /* default empty */
690  {
691  ShaderGraph *graph = new ShaderGraph();
692 
694  shader->name = "default_empty";
695  shader->set_graph(graph);
697  shader->tag_update(scene);
698  }
699 }
700 
702  DeviceRequestedFeatures *requested_features)
703 {
704  foreach (ShaderNode *node, graph->nodes) {
705  requested_features->max_nodes_group = max(requested_features->max_nodes_group,
706  node->get_group());
707  requested_features->nodes_features |= node->get_feature();
708  if (node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) {
709  BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode *>(node);
710  if (CLOSURE_IS_VOLUME(bsdf_node->get_closure_type())) {
711  requested_features->nodes_features |= NODE_FEATURE_VOLUME;
712  }
713  else if (CLOSURE_IS_PRINCIPLED(bsdf_node->get_closure_type())) {
714  requested_features->use_principled = true;
715  }
716  }
717  if (node->has_surface_bssrdf()) {
718  requested_features->use_subsurface = true;
719  }
720  if (node->has_surface_transparent()) {
721  requested_features->use_transparent = true;
722  }
723  if (node->has_raytrace()) {
724  requested_features->use_shader_raytrace = true;
725  }
726  }
727 }
728 
730  DeviceRequestedFeatures *requested_features)
731 {
732  requested_features->max_nodes_group = NODE_GROUP_LEVEL_0;
733  requested_features->nodes_features = 0;
734  for (int i = 0; i < scene->shaders.size(); i++) {
735  Shader *shader = scene->shaders[i];
736  if (!shader->used) {
737  continue;
738  }
739 
740  /* Gather requested features from all the nodes from the graph nodes. */
741  get_requested_graph_features(shader->graph, requested_features);
742  ShaderNode *output_node = shader->graph->output();
743  if (output_node->input("Displacement")->link != NULL) {
744  requested_features->nodes_features |= NODE_FEATURE_BUMP;
745  if (shader->get_displacement_method() == DISPLACE_BOTH) {
746  requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE;
747  requested_features->max_nodes_group = max(requested_features->max_nodes_group,
749  }
750  }
751  /* On top of volume nodes, also check if we need volume sampling because
752  * e.g. an Emission node would slip through the NODE_FEATURE_VOLUME check */
753  if (shader->has_volume)
754  requested_features->use_volume |= true;
755  }
756 }
757 
759 {
760  beckmann_table.free_memory();
761 
762 #ifdef WITH_OSL
763  OSLShaderManager::free_memory();
764 #endif
765 
767 }
768 
770 {
771  return dot(c, rgb_to_y);
772 }
773 
775 {
776  string manifest = "{";
777  unordered_set<ustring, ustringHash> materials;
778  foreach (Shader *shader, scene->shaders) {
779  if (materials.count(shader->name)) {
780  continue;
781  }
782  materials.insert(shader->name);
783  uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
784  manifest += string_printf("\"%s\":\"%08x\",", shader->name.c_str(), cryptomatte_id);
785  }
786  manifest[manifest.size() - 1] = '}';
787  return manifest;
788 }
789 
790 void ShaderManager::tag_update(Scene * /*scene*/, uint32_t /*flag*/)
791 {
792  /* update everything for now */
794 }
795 
797 {
798  return update_flags != UPDATE_NONE;
799 }
800 
801 #ifdef WITH_OCIO
802 static bool to_scene_linear_transform(OCIO::ConstConfigRcPtr &config,
803  const char *colorspace,
804  Transform &to_scene_linear)
805 {
806  OCIO::ConstProcessorRcPtr processor;
807  try {
808  processor = config->getProcessor(OCIO::ROLE_SCENE_LINEAR, colorspace);
809  }
810  catch (OCIO::Exception &) {
811  return false;
812  }
813 
814  if (!processor) {
815  return false;
816  }
817 
818  OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
819  if (!device_processor) {
820  return false;
821  }
822 
823  to_scene_linear = transform_identity();
824  device_processor->applyRGB(&to_scene_linear.x.x);
825  device_processor->applyRGB(&to_scene_linear.y.x);
826  device_processor->applyRGB(&to_scene_linear.z.x);
827  to_scene_linear = transform_transposed_inverse(to_scene_linear);
828  return true;
829 }
830 #endif
831 
833 {
834  /* Default to ITU-BT.709 in case no appropriate transform found.
835  * Note XYZ here is defined as having a D65 white point. */
836  xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f);
837  xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f);
838  xyz_to_b = make_float3(0.0556434f, -0.2040259f, 1.0572252f);
839  rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f);
840 
841 #ifdef WITH_OCIO
842  /* Get from OpenColorO config if it has the required roles. */
843  OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
844  if (!(config && config->hasRole(OCIO::ROLE_SCENE_LINEAR))) {
845  return;
846  }
847 
849 
850  if (config->hasRole("aces_interchange")) {
851  /* Standard OpenColorIO role, defined as ACES2065-1. */
852  const Transform xyz_E_to_aces = make_transform(1.0498110175f,
853  0.0f,
854  -0.0000974845f,
855  0.0f,
856  -0.4959030231f,
857  1.3733130458f,
858  0.0982400361f,
859  0.0f,
860  0.0f,
861  0.0f,
862  0.9912520182f,
863  0.0f);
864  const Transform xyz_D65_to_E = make_transform(
865  1.0521111f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.9184170f, 0.0f);
866 
867  Transform aces_to_rgb;
868  if (!to_scene_linear_transform(config, "aces_interchange", aces_to_rgb)) {
869  return;
870  }
871 
872  xyz_to_rgb = aces_to_rgb * xyz_E_to_aces * xyz_D65_to_E;
873  }
874  else if (config->hasRole("XYZ")) {
875  /* Custom role used before the standard existed. */
876  if (!to_scene_linear_transform(config, "XYZ", xyz_to_rgb)) {
877  return;
878  }
879  }
880  else {
881  /* No reference role found to determine XYZ. */
882  return;
883  }
884 
888 
889  const Transform rgb_to_xyz = transform_inverse(xyz_to_rgb);
890  rgb_to_y = float4_to_float3(rgb_to_xyz.y);
891 #endif
892 }
893 
typedef float(TangentPoint)[2]
MINLINE float safe_sqrtf(float a)
unsigned int uint
Definition: BLI_sys_types.h:83
typedef double(DMatrix)[4][4]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
#define U
unsigned int U
Definition: btGjkEpa3.h:78
#define output
void add(ustring name)
Definition: attribute.cpp:770
bool modified(const AttributeRequestSet &other)
Definition: attribute.cpp:749
Shader * get_shader(const Scene *scene)
virtual ClosureType get_closure_type()
Definition: nodes.h:537
static void free_memory()
Definition: colorspace.cpp:384
bool has_volume_decoupled
Definition: device.h:81
device_vector< KernelShader > shaders
Definition: scene.h:125
KernelData data
Definition: scene.h:136
Definition: device.h:293
DeviceInfo info
Definition: device.h:337
@ SHADER_DISPLACEMENT_MODIFIED
Definition: geometry.h:208
@ SHADER_ATTRIBUTE_MODIFIED
Definition: geometry.h:207
void tag_update(Scene *scene, uint32_t flag)
Definition: geometry.cpp:2127
bool need_flags_update
Definition: geometry.h:224
bool need_update_background
Definition: light.h:114
@ SHADER_MODIFIED
Definition: light.h:103
bool has_background_light(Scene *scene)
Definition: light.cpp:207
void tag_update(Scene *scene, uint32_t flag)
Definition: light.cpp:1036
size_t add_table(DeviceScene *dscene, vector< float > &data)
Definition: tables.cpp:73
void remove_table(size_t *offset)
Definition: tables.cpp:108
bool need_flags_update
Definition: object.h:145
string displacement_hash
Definition: graph.h:321
list< ShaderNode * > nodes
Definition: graph.h:317
OutputNode * output()
Definition: graph.cpp:242
void compute_displacement_hash()
Definition: graph.cpp:745
void remove_proxy_nodes()
Definition: graph.cpp:467
ShaderOutput * link
Definition: graph.h:112
string get_cryptomatte_materials(Scene *scene)
Definition: shader.cpp:774
float3 xyz_to_b
Definition: shader.h:247
float3 xyz_to_r
Definition: shader.h:245
void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
Definition: shader.cpp:512
static bool beckmann_table_ready
Definition: shader.h:236
static void free_memory()
Definition: shader.cpp:758
uint get_attribute_id(ustring name)
Definition: shader.cpp:429
AttributeIDMap unique_attribute_id
Definition: shader.h:232
float linear_rgb_to_gray(float3 c)
Definition: shader.cpp:769
void init_xyz_transforms()
Definition: shader.cpp:832
size_t beckmann_table_offset
Definition: shader.h:238
thread_spin_lock attribute_lock_
Definition: shader.h:243
void get_requested_features(Scene *scene, DeviceRequestedFeatures *requested_features)
Definition: shader.cpp:729
float3 xyz_to_g
Definition: shader.h:246
virtual ~ShaderManager()
Definition: shader.cpp:406
int get_shader_id(Shader *shader, bool smooth=false)
Definition: shader.cpp:449
void get_requested_graph_features(ShaderGraph *graph, DeviceRequestedFeatures *requested_features)
Definition: shader.cpp:701
bool need_update() const
Definition: shader.cpp:796
static ShaderManager * create(int shadingsystem)
Definition: shader.cpp:410
void device_free_common(Device *device, DeviceScene *dscene, Scene *scene)
Definition: shader.cpp:618
static vector< float > beckmann_table
Definition: shader.h:235
void update_shaders_used(Scene *scene)
Definition: shader.cpp:464
static thread_mutex lookup_table_mutex
Definition: shader.h:234
float3 rgb_to_y
Definition: shader.h:248
void tag_update(Scene *scene, uint32_t flag)
Definition: shader.cpp:790
@ SHADER_MODIFIED
Definition: shader.h:170
static void add_default(Scene *scene)
Definition: shader.cpp:625
uint32_t update_flags
Definition: shader.h:229
ShaderInput * input(const char *name)
Definition: graph.cpp:111
ShaderOutput * output(const char *name)
Definition: graph.cpp:121
ShaderNode * parent
Definition: graph.h:139
Definition: shader.h:80
bool has_surface_spatial_varying
Definition: shader.h:125
bool has_surface_bssrdf
Definition: shader.h:122
bool need_update_attribute
Definition: shader.h:104
Shader()
Definition: shader.cpp:197
bool has_volume_attribute_dependency
Definition: shader.h:127
void set_graph(ShaderGraph *graph)
Definition: shader.cpp:279
bool need_update_geometry() const
Definition: shader.cpp:391
bool has_volume
Definition: shader.h:120
bool used
Definition: shader.h:135
bool has_surface
Definition: shader.h:117
bool has_bssrdf_bump
Definition: shader.h:124
NODE_DECLARE ShaderGraph * graph
Definition: shader.h:85
float prev_volume_step_rate
Definition: shader.h:100
bool has_integrator_dependency
Definition: shader.h:128
bool need_update_displacement
Definition: shader.h:105
bool has_surface_emission
Definition: shader.h:118
bool need_update_uvs
Definition: shader.h:103
bool has_displacement
Definition: shader.h:121
bool has_bump
Definition: shader.h:123
AttributeRequestSet attributes
Definition: shader.h:131
bool has_surface_transparent
Definition: shader.h:119
void tag_update(Scene *scene)
Definition: shader.cpp:311
bool is_constant_emission(float3 *emission)
Definition: shader.cpp:233
bool has_volume_connected
Definition: shader.h:114
void tag_used(Scene *scene)
Definition: shader.cpp:381
bool has_volume_spatial_varying
Definition: shader.h:126
~Shader()
Definition: shader.cpp:228
T * alloc(size_t width, size_t height=0, size_t depth=0)
void copy_to_device()
OperationNode * node
Depsgraph * graph
Scene scene
#define function_bind
@ SHADER_SPECIAL_TYPE_OUTPUT_AOV
Definition: graph.h:70
@ SHADER_SPECIAL_TYPE_CLOSURE
Definition: graph.h:66
CCL_NAMESPACE_BEGIN ccl_device float3 xyz_to_rgb(KernelGlobals *kg, float3 xyz)
Definition: kernel_color.h:24
#define expf(x)
#define CCL_NAMESPACE_END
#define fmaxf(x, y)
#define make_float3(x, y, z)
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
@ SD_VOLUME_MIS
Definition: kernel_types.h:883
@ SD_HAS_TRANSPARENT_SHADOW
Definition: kernel_types.h:871
@ SD_VOLUME_EQUIANGULAR
Definition: kernel_types.h:881
@ SD_HAS_BUMP
Definition: kernel_types.h:887
@ SD_HAS_CONSTANT_EMISSION
Definition: kernel_types.h:891
@ SD_HAS_DISPLACEMENT
Definition: kernel_types.h:889
@ SD_HAS_BSSRDF_BUMP
Definition: kernel_types.h:879
@ SD_HAS_ONLY_VOLUME
Definition: kernel_types.h:875
@ SD_VOLUME_CUBIC
Definition: kernel_types.h:885
@ SD_HAS_VOLUME
Definition: kernel_types.h:873
@ SD_USE_MIS
Definition: kernel_types.h:869
@ SD_NEED_VOLUME_ATTRIBUTES
Definition: kernel_types.h:893
@ SD_HETEROGENEOUS_VOLUME
Definition: kernel_types.h:877
AttributeStandard
Definition: kernel_types.h:744
@ ATTR_STD_NUM
Definition: kernel_types.h:771
@ ATTR_STD_POSITION_UNDISPLACED
Definition: kernel_types.h:755
#define BECKMANN_TABLE_SIZE
Definition: kernel_types.h:56
@ SHADER_AREA_LIGHT
Definition: kernel_types.h:583
@ SHADER_SMOOTH_NORMAL
Definition: kernel_types.h:581
@ SHADER_CAST_SHADOW
Definition: kernel_types.h:582
static unsigned c
Definition: RandGen.cpp:97
#define SOCKET_FLOAT(name, ui_name, default_value,...)
Definition: node_type.h:204
#define SOCKET_INT(name, ui_name, default_value,...)
Definition: node_type.h:200
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition: node_type.h:198
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition: node_type.h:220
static void beckmann_table_rows(float *table, int row_from, int row_to)
Definition: shader.cpp:79
static void beckmann_table_build(vector< float > &table)
Definition: shader.cpp:144
NODE_DEFINE(Shader)
Definition: shader.cpp:159
#define MSVC_VOLATILE
Definition: shader.cpp:71
static float beckmann_table_P22(const float slope_x, const float slope_y)
Definition: shader.cpp:54
static float beckmann_table_slope_max()
Definition: shader.cpp:60
@ VOLUME_INTERPOLATION_LINEAR
Definition: shader.h:60
@ VOLUME_INTERPOLATION_CUBIC
Definition: shader.h:61
@ DISPLACE_BUMP
Definition: shader.h:67
@ DISPLACE_TRUE
Definition: shader.h:68
@ DISPLACE_BOTH
Definition: shader.h:69
@ SHADINGSYSTEM_OSL
Definition: shader.h:48
@ VOLUME_SAMPLING_DISTANCE
Definition: shader.h:52
@ VOLUME_SAMPLING_EQUIANGULAR
Definition: shader.h:53
@ VOLUME_SAMPLING_MULTIPLE_IMPORTANCE
Definition: shader.h:54
unsigned int uint32_t
Definition: stdint.h:83
KernelFilm film
KernelTables tables
KernelIntegrator integrator
float4 xyz_to_r
float4 xyz_to_b
float4 xyz_to_g
float4 rgb_to_y
float constant_emission[3]
float cryptomatte_id
void insert(const char *x, int y)
Definition: node_enum.h:33
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
Definition: node.h:98
const NodeType * type
Definition: node.h:175
void tag_modified()
Definition: node.cpp:786
T * create_node(Args &&... args)
Definition: scene.h:302
vector< Geometry * > geometry
Definition: scene.h:235
vector< Shader * > shaders
Definition: scene.h:236
vector< Procedural * > procedurals
Definition: scene.h:240
Shader * default_volume
Definition: scene.h:254
LookupTables * lookup_tables
Definition: scene.h:228
vector< Light * > lights
Definition: scene.h:237
Shader * default_surface
Definition: scene.h:253
Shader * default_empty
Definition: scene.h:257
Shader * default_background
Definition: scene.h:256
ObjectManager * object_manager
Definition: scene.h:247
Background * background
Definition: scene.h:230
ProceduralManager * procedural_manager
Definition: scene.h:250
ShaderManager * shader_manager
Definition: scene.h:245
LightManager * light_manager
Definition: scene.h:244
Shader * default_light
Definition: scene.h:255
GeometryManager * geometry_manager
Definition: scene.h:246
void push(TaskRunFunction &&task)
Definition: util_task.cpp:36
void wait_work(Summary *stats=NULL)
Definition: util_task.cpp:42
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
#define CLOSURE_IS_VOLUME(type)
Definition: svm_types.h:627
#define NODE_FEATURE_BUMP
Definition: svm_types.h:50
#define NODE_GROUP_LEVEL_0
Definition: svm_types.h:41
#define NODE_FEATURE_BUMP_STATE
Definition: svm_types.h:51
#define CLOSURE_IS_PRINCIPLED(type)
Definition: svm_types.h:635
#define NODE_FEATURE_VOLUME
Definition: svm_types.h:48
#define NODE_GROUP_LEVEL_1
Definition: svm_types.h:42
@ TABLE_OFFSET_INVALID
Definition: tables.h:30
float max
ccl_device_inline float4 float3_to_float4(const float3 a)
Definition: util_math.h:420
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition: util_math.h:415
ccl_device_inline float dot(const float2 &a, const float2 &b)
ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t)
ccl_device_inline float3 zero_float3()
float util_hash_to_float(uint32_t hash)
uint32_t util_murmur_hash3(const void *key, int len, uint32_t seed)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
Definition: util_string.cpp:32
std::unique_lock< std::mutex > thread_scoped_lock
Definition: util_thread.h:41
CCL_NAMESPACE_BEGIN typedef std::mutex thread_mutex
Definition: util_thread.h:40
Transform transform_transposed_inverse(const Transform &tfm)
Transform transform_inverse(const Transform &tfm)
ccl_device_inline Transform transform_identity()
ccl_device_inline Transform make_transform(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l)