Blender  V3.3
osl.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #include "device/device.h"
5 
6 #include "scene/background.h"
7 #include "scene/colorspace.h"
8 #include "scene/light.h"
9 #include "scene/osl.h"
10 #include "scene/scene.h"
11 #include "scene/shader.h"
12 #include "scene/shader_graph.h"
13 #include "scene/shader_nodes.h"
14 #include "scene/stats.h"
15 
16 #ifdef WITH_OSL
17 
18 # include "kernel/osl/globals.h"
19 # include "kernel/osl/services.h"
20 # include "kernel/osl/shader.h"
21 
22 # include "util/aligned_malloc.h"
23 # include "util/foreach.h"
24 # include "util/log.h"
25 # include "util/md5.h"
26 # include "util/path.h"
27 # include "util/progress.h"
28 # include "util/projection.h"
29 
30 #endif
31 
33 
34 #ifdef WITH_OSL
35 
36 /* Shared Texture and Shading System */
37 
38 OSL::TextureSystem *OSLShaderManager::ts_shared = NULL;
39 int OSLShaderManager::ts_shared_users = 0;
40 thread_mutex OSLShaderManager::ts_shared_mutex;
41 
42 OSL::ShadingSystem *OSLShaderManager::ss_shared = NULL;
43 OSLRenderServices *OSLShaderManager::services_shared = NULL;
44 int OSLShaderManager::ss_shared_users = 0;
45 thread_mutex OSLShaderManager::ss_shared_mutex;
46 thread_mutex OSLShaderManager::ss_mutex;
47 int OSLCompiler::texture_shared_unique_id = 0;
48 
49 /* Shader Manager */
50 
51 OSLShaderManager::OSLShaderManager()
52 {
53  texture_system_init();
54  shading_system_init();
55 }
56 
57 OSLShaderManager::~OSLShaderManager()
58 {
59  shading_system_free();
60  texture_system_free();
61 }
62 
63 void OSLShaderManager::free_memory()
64 {
65 # ifdef OSL_HAS_BLENDER_CLEANUP_FIX
66  /* There is a problem with LLVM+OSL: The order global destructors across
67  * different compilation units run cannot be guaranteed, on windows this means
68  * that the LLVM destructors run before the osl destructors, causing a crash
69  * when the process exits. the OSL in svn has a special cleanup hack to
70  * sidestep this behavior */
71  OSL::pvt::LLVM_Util::Cleanup();
72 # endif
73 }
74 
75 void OSLShaderManager::reset(Scene * /*scene*/)
76 {
77  shading_system_free();
78  shading_system_init();
79 }
80 
81 void OSLShaderManager::device_update_specific(Device *device,
82  DeviceScene *dscene,
83  Scene *scene,
84  Progress &progress)
85 {
86  if (!need_update())
87  return;
88 
89  scoped_callback_timer timer([scene](double time) {
90  if (scene->update_stats) {
91  scene->update_stats->osl.times.add_entry({"device_update", time});
92  }
93  });
94 
95  VLOG_INFO << "Total " << scene->shaders.size() << " shaders.";
96 
97  device_free(device, dscene, scene);
98 
99  /* set texture system */
101 
102  /* create shaders */
103  OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
104  Shader *background_shader = scene->background->get_shader(scene);
105 
106  foreach (Shader *shader, scene->shaders) {
107  assert(shader->graph);
108 
109  if (progress.get_cancel())
110  return;
111 
112  /* we can only compile one shader at the time as the OSL ShadingSytem
113  * has a single state, but we put the lock here so different renders can
114  * compile shaders alternating */
115  thread_scoped_lock lock(ss_mutex);
116 
117  OSLCompiler compiler(this, services, ss, scene);
118  compiler.background = (shader == background_shader);
119  compiler.compile(og, shader);
120 
121  if (shader->get_use_mis() && shader->has_surface_emission)
123  }
124 
125  /* setup shader engine */
126  og->ss = ss;
127  og->ts = ts;
128  og->services = services;
129 
130  int background_id = scene->shader_manager->get_shader_id(background_shader);
131  og->background_state = og->surface_state[background_id & SHADER_MASK];
132  og->use = true;
133 
134  foreach (Shader *shader, scene->shaders)
135  shader->clear_modified();
136 
137  update_flags = UPDATE_NONE;
138 
139  /* add special builtin texture types */
140  services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
141  services->textures.insert(ustring("@bevel"), new OSLTextureHandle(OSLTextureHandle::BEVEL));
142 
143  device_update_common(device, dscene, scene, progress);
144 
145  {
146  /* Perform greedyjit optimization.
147  *
148  * This might waste time on optimizing groups which are never actually
149  * used, but this prevents OSL from allocating data on TLS at render
150  * time.
151  *
152  * This is much better for us because this way we aren't required to
153  * stop task scheduler threads to make sure all TLS is clean and don't
154  * have issues with TLS data free accessing freed memory if task scheduler
155  * is being freed after the Session is freed.
156  */
157  thread_scoped_lock lock(ss_shared_mutex);
158  ss->optimize_all_groups();
159  }
160 }
161 
162 void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *scene)
163 {
164  OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
165 
166  device_free_common(device, dscene, scene);
167 
168  /* clear shader engine */
169  og->use = false;
170  og->ss = NULL;
171  og->ts = NULL;
172 
173  og->surface_state.clear();
174  og->volume_state.clear();
175  og->displacement_state.clear();
176  og->bump_state.clear();
177  og->background_state.reset();
178 }
179 
180 void OSLShaderManager::texture_system_init()
181 {
182  /* create texture system, shared between different renders to reduce memory usage */
183  thread_scoped_lock lock(ts_shared_mutex);
184 
185  if (ts_shared_users == 0) {
186  ts_shared = TextureSystem::create(true);
187 
188  ts_shared->attribute("automip", 1);
189  ts_shared->attribute("autotile", 64);
190  ts_shared->attribute("gray_to_rgb", 1);
191 
192  /* effectively unlimited for now, until we support proper mipmap lookups */
193  ts_shared->attribute("max_memory_MB", 16384);
194  }
195 
196  ts = ts_shared;
197  ts_shared_users++;
198 }
199 
200 void OSLShaderManager::texture_system_free()
201 {
202  /* shared texture system decrease users and destroy if no longer used */
203  thread_scoped_lock lock(ts_shared_mutex);
204  ts_shared_users--;
205 
206  if (ts_shared_users == 0) {
207  ts_shared->invalidate_all(true);
208  OSL::TextureSystem::destroy(ts_shared);
209  ts_shared = NULL;
210  }
211 
212  ts = NULL;
213 }
214 
215 void OSLShaderManager::shading_system_init()
216 {
217  /* create shading system, shared between different renders to reduce memory usage */
218  thread_scoped_lock lock(ss_shared_mutex);
219 
220  if (ss_shared_users == 0) {
221  /* Must use aligned new due to concurrent hash map. */
222  services_shared = util_aligned_new<OSLRenderServices>(ts_shared);
223 
224  string shader_path = path_get("shader");
225 # ifdef _WIN32
226  /* Annoying thing, Cycles stores paths in UTF-8 codepage, so it can
227  * operate with file paths with any character. This requires to use wide
228  * char functions, but OSL uses old fashioned ANSI functions which means:
229  *
230  * - We have to convert our paths to ANSI before passing to OSL
231  * - OSL can't be used when there's a multi-byte character in the path
232  * to the shaders folder.
233  */
234  shader_path = string_to_ansi(shader_path);
235 # endif
236 
237  ss_shared = new OSL::ShadingSystem(services_shared, ts_shared, &errhandler);
238  ss_shared->attribute("lockgeom", 1);
239  ss_shared->attribute("commonspace", "world");
240  ss_shared->attribute("searchpath:shader", shader_path);
241  ss_shared->attribute("greedyjit", 1);
242 
243  VLOG_INFO << "Using shader search path: " << shader_path;
244 
245  /* our own ray types */
246  static const char *raytypes[] = {
247  "camera", /* PATH_RAY_CAMERA */
248  "reflection", /* PATH_RAY_REFLECT */
249  "refraction", /* PATH_RAY_TRANSMIT */
250  "diffuse", /* PATH_RAY_DIFFUSE */
251  "glossy", /* PATH_RAY_GLOSSY */
252  "singular", /* PATH_RAY_SINGULAR */
253  "transparent", /* PATH_RAY_TRANSPARENT */
254  "volume_scatter", /* PATH_RAY_VOLUME_SCATTER */
255 
256  "shadow", /* PATH_RAY_SHADOW_OPAQUE */
257  "shadow", /* PATH_RAY_SHADOW_TRANSPARENT */
258 
259  "__unused__", /* PATH_RAY_NODE_UNALIGNED */
260  "__unused__", /* PATH_RAY_MIS_SKIP */
261 
262  "diffuse_ancestor", /* PATH_RAY_DIFFUSE_ANCESTOR */
263 
264  /* Remaining irrelevant bits up to 32. */
265  "__unused__",
266  "__unused__",
267  "__unused__",
268  "__unused__",
269  "__unused__",
270  "__unused__",
271  "__unused__",
272  "__unused__",
273  "__unused__",
274  "__unused__",
275  "__unused__",
276  "__unused__",
277  "__unused__",
278  "__unused__",
279  "__unused__",
280  "__unused__",
281  "__unused__",
282  "__unused__",
283  "__unused__",
284  };
285 
286  const int nraytypes = sizeof(raytypes) / sizeof(raytypes[0]);
287  ss_shared->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
288 
289  OSLShader::register_closures((OSLShadingSystem *)ss_shared);
290 
291  loaded_shaders.clear();
292  }
293 
294  ss = ss_shared;
295  services = services_shared;
296  ss_shared_users++;
297 }
298 
299 void OSLShaderManager::shading_system_free()
300 {
301  /* shared shading system decrease users and destroy if no longer used */
302  thread_scoped_lock lock(ss_shared_mutex);
303  ss_shared_users--;
304 
305  if (ss_shared_users == 0) {
306  delete ss_shared;
307  ss_shared = NULL;
308 
309  util_aligned_delete(services_shared);
310  services_shared = NULL;
311  }
312 
313  ss = NULL;
314  services = NULL;
315 }
316 
317 bool OSLShaderManager::osl_compile(const string &inputfile, const string &outputfile)
318 {
320  string stdosl_path;
321  string shader_path = path_get("shader");
322 
323  /* Specify output file name. */
324  options.push_back("-o");
325  options.push_back(outputfile);
326 
327  /* Specify standard include path. */
328  string include_path_arg = string("-I") + shader_path;
329  options.push_back(include_path_arg);
330 
331  stdosl_path = path_join(shader_path, "stdcycles.h");
332 
333  /* Compile.
334  *
335  * Mutex protected because the OSL compiler does not appear to be thread safe, see T92503. */
336  static thread_mutex osl_compiler_mutex;
337  thread_scoped_lock lock(osl_compiler_mutex);
338 
339  OSL::OSLCompiler *compiler = new OSL::OSLCompiler(&OSL::ErrorHandler::default_handler());
340  bool ok = compiler->compile(string_view(inputfile), options, string_view(stdosl_path));
341  delete compiler;
342 
343  return ok;
344 }
345 
346 bool OSLShaderManager::osl_query(OSL::OSLQuery &query, const string &filepath)
347 {
348  string searchpath = path_user_get("shaders");
349  return query.open(filepath, searchpath);
350 }
351 
352 static string shader_filepath_hash(const string &filepath, uint64_t modified_time)
353 {
354  /* compute a hash from filepath and modified time to detect changes */
355  MD5Hash md5;
356  md5.append((const uint8_t *)filepath.c_str(), filepath.size());
357  md5.append((const uint8_t *)&modified_time, sizeof(modified_time));
358 
359  return md5.get_hex();
360 }
361 
362 const char *OSLShaderManager::shader_test_loaded(const string &hash)
363 {
364  map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
365  return (it == loaded_shaders.end()) ? NULL : it->first.c_str();
366 }
367 
368 OSLShaderInfo *OSLShaderManager::shader_loaded_info(const string &hash)
369 {
370  map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
371  return (it == loaded_shaders.end()) ? NULL : &it->second;
372 }
373 
374 const char *OSLShaderManager::shader_load_filepath(string filepath)
375 {
376  size_t len = filepath.size();
377  string extension = filepath.substr(len - 4);
378  uint64_t modified_time = path_modified_time(filepath);
379 
380  if (extension == ".osl") {
381  /* .OSL File */
382  string osopath = filepath.substr(0, len - 4) + ".oso";
383  uint64_t oso_modified_time = path_modified_time(osopath);
384 
385  /* test if we have loaded the corresponding .OSO already */
386  if (oso_modified_time != 0) {
387  const char *hash = shader_test_loaded(shader_filepath_hash(osopath, oso_modified_time));
388 
389  if (hash)
390  return hash;
391  }
392 
393  /* Auto-compile .OSL to .OSO if needed. */
394  if (oso_modified_time == 0 || (oso_modified_time < modified_time)) {
395  OSLShaderManager::osl_compile(filepath, osopath);
396  modified_time = path_modified_time(osopath);
397  }
398  else
399  modified_time = oso_modified_time;
400 
401  filepath = osopath;
402  }
403  else {
404  if (extension == ".oso") {
405  /* .OSO File, nothing to do */
406  }
407  else if (path_dirname(filepath) == "") {
408  /* .OSO File in search path */
409  filepath = path_join(path_user_get("shaders"), filepath + ".oso");
410  }
411  else {
412  /* unknown file */
413  return NULL;
414  }
415 
416  /* test if we have loaded this .OSO already */
417  const char *hash = shader_test_loaded(shader_filepath_hash(filepath, modified_time));
418 
419  if (hash)
420  return hash;
421  }
422 
423  /* read oso bytecode from file */
424  string bytecode_hash = shader_filepath_hash(filepath, modified_time);
425  string bytecode;
426 
427  if (!path_read_text(filepath, bytecode)) {
428  fprintf(stderr, "Cycles shader graph: failed to read file %s\n", filepath.c_str());
429  OSLShaderInfo info;
430  loaded_shaders[bytecode_hash] = info; /* to avoid repeat tries */
431  return NULL;
432  }
433 
434  return shader_load_bytecode(bytecode_hash, bytecode);
435 }
436 
437 const char *OSLShaderManager::shader_load_bytecode(const string &hash, const string &bytecode)
438 {
439  ss->LoadMemoryCompiledShader(hash.c_str(), bytecode.c_str());
440 
441  OSLShaderInfo info;
442 
443  if (!info.query.open_bytecode(bytecode)) {
444  fprintf(stderr, "OSL query error: %s\n", info.query.geterror().c_str());
445  }
446 
447  /* this is a bit weak, but works */
448  info.has_surface_emission = (bytecode.find("\"emission\"") != string::npos);
449  info.has_surface_transparent = (bytecode.find("\"transparent\"") != string::npos);
450  info.has_surface_bssrdf = (bytecode.find("\"bssrdf\"") != string::npos);
451 
452  loaded_shaders[hash] = info;
453 
454  return loaded_shaders.find(hash)->first.c_str();
455 }
456 
457 /* This is a static function to avoid RTTI link errors with only this
458  * file being compiled without RTTI to match OSL and LLVM libraries. */
459 OSLNode *OSLShaderManager::osl_node(ShaderGraph *graph,
460  ShaderManager *manager,
461  const std::string &filepath,
462  const std::string &bytecode_hash,
463  const std::string &bytecode)
464 {
465  if (!manager->use_osl()) {
466  return NULL;
467  }
468 
469  /* create query */
470  OSLShaderManager *osl_manager = static_cast<OSLShaderManager *>(manager);
471  const char *hash;
472 
473  if (!filepath.empty()) {
474  hash = osl_manager->shader_load_filepath(filepath);
475  }
476  else {
477  hash = osl_manager->shader_test_loaded(bytecode_hash);
478  if (!hash)
479  hash = osl_manager->shader_load_bytecode(bytecode_hash, bytecode);
480  }
481 
482  if (!hash) {
483  return NULL;
484  }
485 
486  OSLShaderInfo *info = osl_manager->shader_loaded_info(hash);
487 
488  /* count number of inputs */
489  size_t num_inputs = 0;
490 
491  for (int i = 0; i < info->query.nparams(); i++) {
492  const OSL::OSLQuery::Parameter *param = info->query.getparam(i);
493 
494  /* skip unsupported types */
495  if (param->varlenarray || param->isstruct || param->type.arraylen > 1)
496  continue;
497 
498  if (!param->isoutput)
499  num_inputs++;
500  }
501 
502  /* create node */
503  OSLNode *node = OSLNode::create(graph, num_inputs);
504 
505  /* add new sockets from parameters */
506  set<void *> used_sockets;
507 
508  for (int i = 0; i < info->query.nparams(); i++) {
509  const OSL::OSLQuery::Parameter *param = info->query.getparam(i);
510 
511  /* skip unsupported types */
512  if (param->varlenarray || param->isstruct || param->type.arraylen > 1)
513  continue;
514 
515  SocketType::Type socket_type;
516 
517  if (param->isclosure) {
518  socket_type = SocketType::CLOSURE;
519  }
520  else if (param->type.vecsemantics != TypeDesc::NOSEMANTICS) {
521  if (param->type.vecsemantics == TypeDesc::COLOR)
522  socket_type = SocketType::COLOR;
523  else if (param->type.vecsemantics == TypeDesc::POINT)
524  socket_type = SocketType::POINT;
525  else if (param->type.vecsemantics == TypeDesc::VECTOR)
526  socket_type = SocketType::VECTOR;
527  else if (param->type.vecsemantics == TypeDesc::NORMAL)
528  socket_type = SocketType::NORMAL;
529  else
530  continue;
531 
532  if (!param->isoutput && param->validdefault) {
533  float3 *default_value = (float3 *)node->input_default_value();
534  default_value->x = param->fdefault[0];
535  default_value->y = param->fdefault[1];
536  default_value->z = param->fdefault[2];
537  }
538  }
539  else if (param->type.aggregate == TypeDesc::SCALAR) {
540  if (param->type.basetype == TypeDesc::INT) {
541  socket_type = SocketType::INT;
542 
543  if (!param->isoutput && param->validdefault) {
544  *(int *)node->input_default_value() = param->idefault[0];
545  }
546  }
547  else if (param->type.basetype == TypeDesc::FLOAT) {
548  socket_type = SocketType::FLOAT;
549 
550  if (!param->isoutput && param->validdefault) {
551  *(float *)node->input_default_value() = param->fdefault[0];
552  }
553  }
554  else if (param->type.basetype == TypeDesc::STRING) {
555  socket_type = SocketType::STRING;
556 
557  if (!param->isoutput && param->validdefault) {
558  *(ustring *)node->input_default_value() = param->sdefault[0];
559  }
560  }
561  else
562  continue;
563  }
564  else
565  continue;
566 
567  if (param->isoutput) {
568  node->add_output(param->name, socket_type);
569  }
570  else {
571  node->add_input(param->name, socket_type);
572  }
573  }
574 
575  /* Set byte-code hash or file-path. */
576  if (!bytecode_hash.empty()) {
577  node->bytecode_hash = bytecode_hash;
578  }
579  else {
580  node->filepath = filepath;
581  }
582 
583  /* Generate inputs and outputs */
584  node->create_inputs_outputs(node->type);
585 
586  return node;
587 }
588 
589 /* Graph Compiler */
590 
591 OSLCompiler::OSLCompiler(OSLShaderManager *manager,
592  OSLRenderServices *services,
593  OSL::ShadingSystem *ss,
594  Scene *scene)
595  : scene(scene), manager(manager), services(services), ss(ss)
596 {
597  current_type = SHADER_TYPE_SURFACE;
598  current_shader = NULL;
599  background = false;
600 }
601 
603 {
604  /* assign layer unique name based on pointer address + bump mode */
605  stringstream stream;
606  stream << "node_" << node->type->name << "_" << node;
607 
608  return stream.str();
609 }
610 
611 string OSLCompiler::compatible_name(ShaderNode *node, ShaderInput *input)
612 {
613  string sname(input->name().string());
614  size_t i;
615 
616  /* Strip white-space. */
617  while ((i = sname.find(" ")) != string::npos)
618  sname.replace(i, 1, "");
619 
620  /* if output exists with the same name, add "In" suffix */
621  foreach (ShaderOutput *output, node->outputs) {
622  if (input->name() == output->name()) {
623  sname += "In";
624  break;
625  }
626  }
627 
628  return sname;
629 }
630 
631 string OSLCompiler::compatible_name(ShaderNode *node, ShaderOutput *output)
632 {
633  string sname(output->name().string());
634  size_t i;
635 
636  /* Strip white-space. */
637  while ((i = sname.find(" ")) != string::npos)
638  sname.replace(i, 1, "");
639 
640  /* if input exists with the same name, add "Out" suffix */
641  foreach (ShaderInput *input, node->inputs) {
642  if (input->name() == output->name()) {
643  sname += "Out";
644  break;
645  }
646  }
647 
648  return sname;
649 }
650 
651 bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
652 {
653  /* exception for output node, only one input is actually used
654  * depending on the current shader type */
655 
656  if (input->flags() & SocketType::SVM_INTERNAL)
657  return true;
658 
659  if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT) {
660  if (input->name() == "Surface" && current_type != SHADER_TYPE_SURFACE)
661  return true;
662  if (input->name() == "Volume" && current_type != SHADER_TYPE_VOLUME)
663  return true;
664  if (input->name() == "Displacement" && current_type != SHADER_TYPE_DISPLACEMENT)
665  return true;
666  if (input->name() == "Normal" && current_type != SHADER_TYPE_BUMP)
667  return true;
668  }
669  else if (node->special_type == SHADER_SPECIAL_TYPE_BUMP) {
670  if (input->name() == "Height")
671  return true;
672  }
673  else if (current_type == SHADER_TYPE_DISPLACEMENT && input->link &&
674  input->link->parent->special_type == SHADER_SPECIAL_TYPE_BUMP)
675  return true;
676 
677  return false;
678 }
679 
680 void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
681 {
682  /* load filepath */
683  if (isfilepath) {
684  name = manager->shader_load_filepath(name);
685 
686  if (name == NULL)
687  return;
688  }
689 
690  /* pass in fixed parameter values */
691  foreach (ShaderInput *input, node->inputs) {
692  if (!input->link) {
693  /* checks to untangle graphs */
694  if (node_skip_input(node, input))
695  continue;
696 
697  string param_name = compatible_name(node, input);
698  const SocketType &socket = input->socket_type;
699  switch (input->type()) {
700  case SocketType::COLOR:
701  parameter_color(param_name.c_str(), node->get_float3(socket));
702  break;
703  case SocketType::POINT:
704  parameter_point(param_name.c_str(), node->get_float3(socket));
705  break;
706  case SocketType::VECTOR:
707  parameter_vector(param_name.c_str(), node->get_float3(socket));
708  break;
709  case SocketType::NORMAL:
710  parameter_normal(param_name.c_str(), node->get_float3(socket));
711  break;
712  case SocketType::FLOAT:
713  parameter(param_name.c_str(), node->get_float(socket));
714  break;
715  case SocketType::INT:
716  parameter(param_name.c_str(), node->get_int(socket));
717  break;
718  case SocketType::STRING:
719  parameter(param_name.c_str(), node->get_string(socket));
720  break;
721  case SocketType::CLOSURE:
723  default:
724  break;
725  }
726  }
727  }
728 
729  /* Create shader of the appropriate type. OSL only distinguishes between "surface"
730  * and "displacement" at the moment. */
731  if (current_type == SHADER_TYPE_SURFACE)
732  ss->Shader("surface", name, id(node).c_str());
733  else if (current_type == SHADER_TYPE_VOLUME)
734  ss->Shader("surface", name, id(node).c_str());
735  else if (current_type == SHADER_TYPE_DISPLACEMENT)
736  ss->Shader("displacement", name, id(node).c_str());
737  else if (current_type == SHADER_TYPE_BUMP)
738  ss->Shader("displacement", name, id(node).c_str());
739  else
740  assert(0);
741 
742  /* link inputs to other nodes */
743  foreach (ShaderInput *input, node->inputs) {
744  if (input->link) {
745  if (node_skip_input(node, input))
746  continue;
747 
748  /* connect shaders */
749  string id_from = id(input->link->parent);
750  string id_to = id(node);
751  string param_from = compatible_name(input->link->parent, input->link);
752  string param_to = compatible_name(node, input);
753 
754  ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str());
755  }
756  }
757 
758  /* test if we shader contains specific closures */
759  OSLShaderInfo *info = manager->shader_loaded_info(name);
760 
761  if (current_type == SHADER_TYPE_SURFACE) {
762  if (info) {
763  if (info->has_surface_emission)
764  current_shader->has_surface_emission = true;
765  if (info->has_surface_transparent)
766  current_shader->has_surface_transparent = true;
767  if (info->has_surface_bssrdf) {
768  current_shader->has_surface_bssrdf = true;
769  current_shader->has_bssrdf_bump = true; /* can't detect yet */
770  }
771  current_shader->has_bump = true; /* can't detect yet */
772  current_shader->has_surface_raytrace = true; /* can't detect yet */
773  }
774 
775  if (node->has_spatial_varying()) {
776  current_shader->has_surface_spatial_varying = true;
777  }
778  }
779  else if (current_type == SHADER_TYPE_VOLUME) {
780  if (node->has_spatial_varying())
781  current_shader->has_volume_spatial_varying = true;
782  if (node->has_attribute_dependency())
783  current_shader->has_volume_attribute_dependency = true;
784  }
785 
786  if (node->has_integrator_dependency()) {
787  current_shader->has_integrator_dependency = true;
788  }
789 }
790 
791 static TypeDesc array_typedesc(TypeDesc typedesc, int arraylength)
792 {
793  return TypeDesc((TypeDesc::BASETYPE)typedesc.basetype,
794  (TypeDesc::AGGREGATE)typedesc.aggregate,
795  (TypeDesc::VECSEMANTICS)typedesc.vecsemantics,
796  arraylength);
797 }
798 
799 void OSLCompiler::parameter(ShaderNode *node, const char *name)
800 {
801  ustring uname = ustring(name);
802  const SocketType &socket = *(node->type->find_input(uname));
803 
804  switch (socket.type) {
805  case SocketType::BOOLEAN: {
806  int value = node->get_bool(socket);
807  ss->Parameter(name, TypeDesc::TypeInt, &value);
808  break;
809  }
810  case SocketType::FLOAT: {
811  float value = node->get_float(socket);
812  ss->Parameter(uname, TypeDesc::TypeFloat, &value);
813  break;
814  }
815  case SocketType::INT: {
816  int value = node->get_int(socket);
817  ss->Parameter(uname, TypeDesc::TypeInt, &value);
818  break;
819  }
820  case SocketType::COLOR: {
821  float3 value = node->get_float3(socket);
822  ss->Parameter(uname, TypeDesc::TypeColor, &value);
823  break;
824  }
825  case SocketType::VECTOR: {
826  float3 value = node->get_float3(socket);
827  ss->Parameter(uname, TypeDesc::TypeVector, &value);
828  break;
829  }
830  case SocketType::POINT: {
831  float3 value = node->get_float3(socket);
832  ss->Parameter(uname, TypeDesc::TypePoint, &value);
833  break;
834  }
835  case SocketType::NORMAL: {
836  float3 value = node->get_float3(socket);
837  ss->Parameter(uname, TypeDesc::TypeNormal, &value);
838  break;
839  }
840  case SocketType::POINT2: {
841  float2 value = node->get_float2(socket);
842  ss->Parameter(uname, TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::POINT), &value);
843  break;
844  }
845  case SocketType::STRING: {
846  ustring value = node->get_string(socket);
847  ss->Parameter(uname, TypeDesc::TypeString, &value);
848  break;
849  }
850  case SocketType::ENUM: {
851  ustring value = node->get_string(socket);
852  ss->Parameter(uname, TypeDesc::TypeString, &value);
853  break;
854  }
855  case SocketType::TRANSFORM: {
856  Transform value = node->get_transform(socket);
857  ProjectionTransform projection(value);
858  projection = projection_transpose(projection);
859  ss->Parameter(uname, TypeDesc::TypeMatrix, &projection);
860  break;
861  }
863  // OSL does not support booleans, so convert to int
864  const array<bool> &value = node->get_bool_array(socket);
865  array<int> intvalue(value.size());
866  for (size_t i = 0; i < value.size(); i++)
867  intvalue[i] = value[i];
868  ss->Parameter(uname, array_typedesc(TypeDesc::TypeInt, value.size()), intvalue.data());
869  break;
870  }
872  const array<float> &value = node->get_float_array(socket);
873  ss->Parameter(uname, array_typedesc(TypeDesc::TypeFloat, value.size()), value.data());
874  break;
875  }
876  case SocketType::INT_ARRAY: {
877  const array<int> &value = node->get_int_array(socket);
878  ss->Parameter(uname, array_typedesc(TypeDesc::TypeInt, value.size()), value.data());
879  break;
880  }
885  TypeDesc typedesc;
886 
887  switch (socket.type) {
889  typedesc = TypeDesc::TypeColor;
890  break;
892  typedesc = TypeDesc::TypeVector;
893  break;
895  typedesc = TypeDesc::TypePoint;
896  break;
898  typedesc = TypeDesc::TypeNormal;
899  break;
900  default:
901  assert(0);
902  break;
903  }
904 
905  // convert to tightly packed array since float3 has padding
906  const array<float3> &value = node->get_float3_array(socket);
907  array<float> fvalue(value.size() * 3);
908  for (size_t i = 0, j = 0; i < value.size(); i++) {
909  fvalue[j++] = value[i].x;
910  fvalue[j++] = value[i].y;
911  fvalue[j++] = value[i].z;
912  }
913 
914  ss->Parameter(uname, array_typedesc(typedesc, value.size()), fvalue.data());
915  break;
916  }
918  const array<float2> &value = node->get_float2_array(socket);
919  ss->Parameter(
920  uname,
921  array_typedesc(TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::POINT), value.size()),
922  value.data());
923  break;
924  }
926  const array<ustring> &value = node->get_string_array(socket);
927  ss->Parameter(uname, array_typedesc(TypeDesc::TypeString, value.size()), value.data());
928  break;
929  }
931  const array<Transform> &value = node->get_transform_array(socket);
932  array<ProjectionTransform> fvalue(value.size());
933  for (size_t i = 0; i < value.size(); i++) {
934  fvalue[i] = projection_transpose(ProjectionTransform(value[i]));
935  }
936  ss->Parameter(uname, array_typedesc(TypeDesc::TypeMatrix, fvalue.size()), fvalue.data());
937  break;
938  }
939  case SocketType::CLOSURE:
940  case SocketType::NODE:
943  case SocketType::UINT: {
944  assert(0);
945  break;
946  }
947  }
948 }
949 
950 void OSLCompiler::parameter(const char *name, float f)
951 {
952  ss->Parameter(name, TypeDesc::TypeFloat, &f);
953 }
954 
955 void OSLCompiler::parameter_color(const char *name, float3 f)
956 {
957  ss->Parameter(name, TypeDesc::TypeColor, &f);
958 }
959 
960 void OSLCompiler::parameter_point(const char *name, float3 f)
961 {
962  ss->Parameter(name, TypeDesc::TypePoint, &f);
963 }
964 
965 void OSLCompiler::parameter_normal(const char *name, float3 f)
966 {
967  ss->Parameter(name, TypeDesc::TypeNormal, &f);
968 }
969 
970 void OSLCompiler::parameter_vector(const char *name, float3 f)
971 {
972  ss->Parameter(name, TypeDesc::TypeVector, &f);
973 }
974 
975 void OSLCompiler::parameter(const char *name, int f)
976 {
977  ss->Parameter(name, TypeDesc::TypeInt, &f);
978 }
979 
980 void OSLCompiler::parameter(const char *name, const char *s)
981 {
982  ss->Parameter(name, TypeDesc::TypeString, &s);
983 }
984 
985 void OSLCompiler::parameter(const char *name, ustring s)
986 {
987  const char *str = s.c_str();
988  ss->Parameter(name, TypeDesc::TypeString, &str);
989 }
990 
991 void OSLCompiler::parameter(const char *name, const Transform &tfm)
992 {
993  ProjectionTransform projection(tfm);
994  projection = projection_transpose(projection);
995  ss->Parameter(name, TypeDesc::TypeMatrix, (float *)&projection);
996 }
997 
998 void OSLCompiler::parameter_array(const char *name, const float f[], int arraylen)
999 {
1000  TypeDesc type = TypeDesc::TypeFloat;
1001  type.arraylen = arraylen;
1002  ss->Parameter(name, type, f);
1003 }
1004 
1005 void OSLCompiler::parameter_color_array(const char *name, const array<float3> &f)
1006 {
1007  /* NOTE: cycles float3 type is actually 4 floats! need to use an explicit array. */
1008  array<float[3]> table(f.size());
1009 
1010  for (int i = 0; i < f.size(); ++i) {
1011  table[i][0] = f[i].x;
1012  table[i][1] = f[i].y;
1013  table[i][2] = f[i].z;
1014  }
1015 
1016  TypeDesc type = TypeDesc::TypeColor;
1017  type.arraylen = table.size();
1018  ss->Parameter(name, type, table.data());
1019 }
1020 
1021 void OSLCompiler::parameter_attribute(const char *name, ustring s)
1022 {
1023  if (Attribute::name_standard(s.c_str()))
1024  parameter(name, (string("geom:") + s.c_str()).c_str());
1025  else
1026  parameter(name, s.c_str());
1027 }
1028 
1029 void OSLCompiler::find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input)
1030 {
1031  ShaderNode *node = (input->link) ? input->link->parent : NULL;
1032 
1033  if (node != NULL && dependencies.find(node) == dependencies.end()) {
1034  foreach (ShaderInput *in, node->inputs)
1035  if (!node_skip_input(node, in))
1036  find_dependencies(dependencies, in);
1037 
1038  dependencies.insert(node);
1039  }
1040 }
1041 
1042 void OSLCompiler::generate_nodes(const ShaderNodeSet &nodes)
1043 {
1044  ShaderNodeSet done;
1045  bool nodes_done;
1046 
1047  do {
1048  nodes_done = true;
1049 
1050  foreach (ShaderNode *node, nodes) {
1051  if (done.find(node) == done.end()) {
1052  bool inputs_done = true;
1053 
1054  foreach (ShaderInput *input, node->inputs)
1055  if (!node_skip_input(node, input))
1056  if (input->link && done.find(input->link->parent) == done.end())
1057  inputs_done = false;
1058 
1059  if (inputs_done) {
1060  node->compile(*this);
1061  done.insert(node);
1062 
1063  if (current_type == SHADER_TYPE_SURFACE) {
1064  if (node->has_surface_emission())
1065  current_shader->has_surface_emission = true;
1066  if (node->has_surface_transparent())
1067  current_shader->has_surface_transparent = true;
1068  if (node->get_feature() & KERNEL_FEATURE_NODE_RAYTRACE)
1069  current_shader->has_surface_raytrace = true;
1070  if (node->has_spatial_varying())
1071  current_shader->has_surface_spatial_varying = true;
1072  if (node->has_surface_bssrdf()) {
1073  current_shader->has_surface_bssrdf = true;
1074  if (node->has_bssrdf_bump())
1075  current_shader->has_bssrdf_bump = true;
1076  }
1077  if (node->has_bump()) {
1078  current_shader->has_bump = true;
1079  }
1080  }
1081  else if (current_type == SHADER_TYPE_VOLUME) {
1082  if (node->has_spatial_varying())
1083  current_shader->has_volume_spatial_varying = true;
1084  }
1085  }
1086  else
1087  nodes_done = false;
1088  }
1089  }
1090  } while (!nodes_done);
1091 }
1092 
1093 OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type)
1094 {
1095  current_type = type;
1096 
1097  OSL::ShaderGroupRef group = ss->ShaderGroupBegin(shader->name.c_str());
1098 
1099  ShaderNode *output = graph->output();
1100  ShaderNodeSet dependencies;
1101 
1102  if (type == SHADER_TYPE_SURFACE) {
1103  /* generate surface shader */
1104  find_dependencies(dependencies, output->input("Surface"));
1105  generate_nodes(dependencies);
1106  output->compile(*this);
1107  }
1108  else if (type == SHADER_TYPE_BUMP) {
1109  /* generate bump shader */
1110  find_dependencies(dependencies, output->input("Normal"));
1111  generate_nodes(dependencies);
1112  output->compile(*this);
1113  }
1114  else if (type == SHADER_TYPE_VOLUME) {
1115  /* generate volume shader */
1116  find_dependencies(dependencies, output->input("Volume"));
1117  generate_nodes(dependencies);
1118  output->compile(*this);
1119  }
1120  else if (type == SHADER_TYPE_DISPLACEMENT) {
1121  /* generate displacement shader */
1122  find_dependencies(dependencies, output->input("Displacement"));
1123  generate_nodes(dependencies);
1124  output->compile(*this);
1125  }
1126  else
1127  assert(0);
1128 
1129  ss->ShaderGroupEnd();
1130 
1131  return group;
1132 }
1133 
1134 void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
1135 {
1136  if (shader->is_modified()) {
1137  ShaderGraph *graph = shader->graph;
1138  ShaderNode *output = (graph) ? graph->output() : NULL;
1139 
1140  bool has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) &&
1141  output->input("Surface")->link && output->input("Displacement")->link;
1142 
1143  /* finalize */
1144  shader->graph->finalize(scene,
1145  has_bump,
1146  shader->has_integrator_dependency,
1147  shader->get_displacement_method() == DISPLACE_BOTH);
1148 
1149  current_shader = shader;
1150 
1151  shader->has_surface = false;
1152  shader->has_surface_emission = false;
1153  shader->has_surface_transparent = false;
1154  shader->has_surface_bssrdf = false;
1155  shader->has_bump = has_bump;
1156  shader->has_bssrdf_bump = has_bump;
1157  shader->has_volume = false;
1158  shader->has_displacement = false;
1159  shader->has_surface_spatial_varying = false;
1160  shader->has_volume_spatial_varying = false;
1161  shader->has_volume_attribute_dependency = false;
1162  shader->has_integrator_dependency = false;
1163 
1164  /* generate surface shader */
1165  if (shader->reference_count() && graph && output->input("Surface")->link) {
1166  shader->osl_surface_ref = compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
1167 
1168  if (has_bump)
1169  shader->osl_surface_bump_ref = compile_type(shader, shader->graph, SHADER_TYPE_BUMP);
1170  else
1171  shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
1172 
1173  shader->has_surface = true;
1174  }
1175  else {
1176  shader->osl_surface_ref = OSL::ShaderGroupRef();
1177  shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
1178  }
1179 
1180  /* generate volume shader */
1181  if (shader->reference_count() && graph && output->input("Volume")->link) {
1182  shader->osl_volume_ref = compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
1183  shader->has_volume = true;
1184  }
1185  else
1186  shader->osl_volume_ref = OSL::ShaderGroupRef();
1187 
1188  /* generate displacement shader */
1189  if (shader->reference_count() && graph && output->input("Displacement")->link) {
1190  shader->osl_displacement_ref = compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
1191  shader->has_displacement = true;
1192  }
1193  else
1194  shader->osl_displacement_ref = OSL::ShaderGroupRef();
1195  }
1196 
1197  /* push state to array for lookup */
1198  og->surface_state.push_back(shader->osl_surface_ref);
1199  og->volume_state.push_back(shader->osl_volume_ref);
1200  og->displacement_state.push_back(shader->osl_displacement_ref);
1201  og->bump_state.push_back(shader->osl_surface_bump_ref);
1202 }
1203 
1204 void OSLCompiler::parameter_texture(const char *name, ustring filename, ustring colorspace)
1205 {
1206  /* Textured loaded through the OpenImageIO texture cache. For this
1207  * case we need to do runtime color space conversion. */
1209  handle->processor = ColorSpaceManager::get_processor(colorspace);
1210  services->textures.insert(filename, handle);
1211  parameter(name, filename);
1212 }
1213 
1214 void OSLCompiler::parameter_texture(const char *name, const ImageHandle &handle)
1215 {
1216  /* Texture loaded through SVM image texture system. We generate a unique
1217  * name, which ends up being used in OSLRenderServices::get_texture_handle
1218  * to get handle again. Note that this name must be unique between multiple
1219  * render sessions as the render services are shared. */
1220  ustring filename(string_printf("@svm%d", texture_shared_unique_id++).c_str());
1221  services->textures.insert(filename,
1223  parameter(name, filename);
1224 }
1225 
1226 void OSLCompiler::parameter_texture_ies(const char *name, int svm_slot)
1227 {
1228  /* IES light textures stored in SVM. */
1229  ustring filename(string_printf("@svm%d", texture_shared_unique_id++).c_str());
1230  services->textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::IES, svm_slot));
1231  parameter(name, filename);
1232 }
1233 
1234 #else
1235 
1236 void OSLCompiler::add(ShaderNode * /*node*/, const char * /*name*/, bool /*isfilepath*/)
1237 {
1238 }
1239 
1240 void OSLCompiler::parameter(ShaderNode * /*node*/, const char * /*name*/)
1241 {
1242 }
1243 
1244 void OSLCompiler::parameter(const char * /*name*/, float /*f*/)
1245 {
1246 }
1247 
1248 void OSLCompiler::parameter_color(const char * /*name*/, float3 /*f*/)
1249 {
1250 }
1251 
1252 void OSLCompiler::parameter_vector(const char * /*name*/, float3 /*f*/)
1253 {
1254 }
1255 
1256 void OSLCompiler::parameter_point(const char * /*name*/, float3 /*f*/)
1257 {
1258 }
1259 
1260 void OSLCompiler::parameter_normal(const char * /*name*/, float3 /*f*/)
1261 {
1262 }
1263 
1264 void OSLCompiler::parameter(const char * /*name*/, int /*f*/)
1265 {
1266 }
1267 
1268 void OSLCompiler::parameter(const char * /*name*/, const char * /*s*/)
1269 {
1270 }
1271 
1272 void OSLCompiler::parameter(const char * /*name*/, ustring /*s*/)
1273 {
1274 }
1275 
1276 void OSLCompiler::parameter(const char * /*name*/, const Transform & /*tfm*/)
1277 {
1278 }
1279 
1280 void OSLCompiler::parameter_array(const char * /*name*/, const float /*f*/[], int /*arraylen*/)
1281 {
1282 }
1283 
1284 void OSLCompiler::parameter_color_array(const char * /*name*/, const array<float3> & /*f*/)
1285 {
1286 }
1287 
1288 void OSLCompiler::parameter_texture(const char * /* name */,
1289  ustring /* filename */,
1290  ustring /* colorspace */)
1291 {
1292 }
1293 
1294 void OSLCompiler::parameter_texture(const char * /* name */, const ImageHandle & /*handle*/)
1295 {
1296 }
1297 
1298 void OSLCompiler::parameter_texture_ies(const char * /* name */, int /* svm_slot */)
1299 {
1300 }
1301 
1302 #endif /* WITH_OSL */
1303 
_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 const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum query
_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
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value NORMAL
volatile int lock
static AttributeStandard name_standard(const char *name)
Shader * get_shader(const Scene *scene)
static ColorSpaceProcessor * get_processor(ustring colorspace)
Definition: colorspace.cpp:34
virtual void * get_cpu_osl_memory()
vector< int4 > get_svm_slots() const
void set_osl_texture_system(void *texture_system)
void tag_update(Scene *scene, uint32_t flag)
Definition: md5.h:20
string get_hex()
Definition: md5.cpp:348
void append(const uint8_t *data, int size)
Definition: md5.cpp:256
void add(ShaderNode *node, const char *name, bool isfilepath=false)
Definition: osl.cpp:1236
void parameter_vector(const char *name, float3 f)
Definition: osl.cpp:1252
void parameter_array(const char *name, const float f[], int arraylen)
Definition: osl.cpp:1280
void parameter_texture_ies(const char *name, int svm_slot)
Definition: osl.cpp:1298
void parameter_texture(const char *name, ustring filename, ustring colorspace)
Definition: osl.cpp:1288
void parameter(ShaderNode *node, const char *name)
Definition: osl.cpp:1240
void parameter_normal(const char *name, float3 f)
Definition: osl.cpp:1260
void parameter_color_array(const char *name, const array< float3 > &f)
Definition: osl.cpp:1284
void compile(OSLGlobals *og, Shader *shader)
Scene * scene
Definition: osl.h:159
void parameter_point(const char *name, float3 f)
Definition: osl.cpp:1256
void parameter_color(const char *name, float3 f)
Definition: osl.cpp:1248
void parameter_attribute(const char *name, ustring s)
static OSLNode * create(ShaderGraph *graph, size_t num_inputs, const OSLNode *from=NULL)
bool get_cancel() const
Definition: progress.h:90
void finalize(Scene *scene, bool do_bump=false, bool do_simplify=false, bool bump_in_object_space=false)
int get_shader_id(Shader *shader, bool smooth=false)
virtual bool use_osl()
Definition: scene/shader.h:178
bool has_surface_spatial_varying
Definition: scene/shader.h:112
bool has_surface_bssrdf
Definition: scene/shader.h:109
bool has_volume_attribute_dependency
Definition: scene/shader.h:114
bool has_volume
Definition: scene/shader.h:107
bool has_surface
Definition: scene/shader.h:103
bool has_bssrdf_bump
Definition: scene/shader.h:111
NODE_DECLARE ShaderGraph * graph
Definition: scene/shader.h:71
bool has_integrator_dependency
Definition: scene/shader.h:115
bool has_surface_emission
Definition: scene/shader.h:104
bool has_surface_raytrace
Definition: scene/shader.h:106
bool has_displacement
Definition: scene/shader.h:108
bool has_bump
Definition: scene/shader.h:110
bool has_surface_transparent
Definition: scene/shader.h:105
bool has_volume_spatial_varying
Definition: scene/shader.h:113
size_t size() const
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
void util_aligned_delete(T *t)
CCL_NAMESPACE_BEGIN struct ProjectionTransform ProjectionTransform
ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform &a)
CCL_NAMESPACE_BEGIN struct Options options
OperationNode * node
Depsgraph * graph
double time
Scene scene
int len
Definition: draw_manager.c:108
#define str(s)
ccl_global KernelShaderEvalInput ccl_global float * output
ccl_global KernelShaderEvalInput * input
ccl_gpu_kernel_postfix ccl_global float int int int int float bool reset
clear internal cached data and reset random seed
ShaderType
@ SHADER_TYPE_BUMP
@ SHADER_TYPE_SURFACE
@ SHADER_TYPE_VOLUME
@ SHADER_TYPE_DISPLACEMENT
@ KERNEL_FEATURE_NODE_RAYTRACE
@ SHADER_MASK
Definition: kernel/types.h:449
#define VLOG_INFO
Definition: log.h:77
static const VertexNature POINT
Definition: Nature.h:20
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRefNull prop_name, int32_t value)
Allocate a new IDProperty of type IDP_INT, set its name and value.
#define hash
Definition: noise.c:153
string path_user_get(const string &sub)
Definition: path.cpp:350
string path_dirname(const string &path)
Definition: path.cpp:399
string path_get(const string &sub)
Definition: path.cpp:338
uint64_t path_modified_time(const string &path)
Definition: path.cpp:715
string path_join(const string &dir, const string &file)
Definition: path.cpp:413
bool path_read_text(const string &path, string &text)
Definition: path.cpp:701
@ FLOAT
@ DISPLACE_TRUE
Definition: scene/shader.h:54
@ DISPLACE_BOTH
Definition: scene/shader.h:55
ShadingSystem
Definition: scene/shader.h:34
@ SHADER_SPECIAL_TYPE_BUMP
Definition: shader_graph.h:56
@ SHADER_SPECIAL_TYPE_OUTPUT
Definition: shader_graph.h:55
set< ShaderNode *, ShaderNodeIDComparator > ShaderNodeSet
Definition: shader_graph.h:289
unsigned char uint8_t
Definition: stdint.h:78
unsigned __int64 uint64_t
Definition: stdint.h:90
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
Definition: string.cpp:22
ustring name
Definition: graph/node.h:174
int reference_count() const
Definition: graph/node.h:180
void clear_modified()
Definition: graph/node.cpp:814
bool is_modified() const
Definition: graph/node.cpp:804
ColorSpaceProcessor * processor
Definition: services.h:63
vector< Shader * > shaders
Definition: scene.h:215
ImageManager * image_manager
Definition: scene.h:222
Background * background
Definition: scene.h:209
ShaderManager * shader_manager
Definition: scene.h:224
LightManager * light_manager
Definition: scene.h:223
SceneUpdateStats * update_stats
Definition: scene.h:249
@ BOOLEAN_ARRAY
Definition: node_type.h:41
@ TRANSFORM_ARRAY
Definition: node_type.h:50
@ NODE_ARRAY
Definition: node_type.h:51
@ POINT2_ARRAY
Definition: node_type.h:48
@ FLOAT_ARRAY
Definition: node_type.h:42
@ NORMAL_ARRAY
Definition: node_type.h:47
@ VECTOR_ARRAY
Definition: node_type.h:45
@ POINT_ARRAY
Definition: node_type.h:46
@ STRING_ARRAY
Definition: node_type.h:49
@ COLOR_ARRAY
Definition: node_type.h:44
Type type
Definition: node_type.h:73
@ SVM_INTERNAL
Definition: node_type.h:58
float z
float y
float x
std::unique_lock< std::mutex > thread_scoped_lock
Definition: thread.h:28
CCL_NAMESPACE_BEGIN typedef std::mutex thread_mutex
Definition: thread.h:27