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