Blender  V2.93
nodes.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 "render/nodes.h"
18 #include "render/colorspace.h"
19 #include "render/constant_fold.h"
20 #include "render/film.h"
21 #include "render/image.h"
22 #include "render/image_sky.h"
23 #include "render/integrator.h"
24 #include "render/light.h"
25 #include "render/mesh.h"
26 #include "render/osl.h"
27 #include "render/scene.h"
28 #include "render/svm.h"
29 
30 #include "sky_model.h"
31 
32 #include "util/util_foreach.h"
33 #include "util/util_logging.h"
34 #include "util/util_transform.h"
35 
40 
42 
43 /* Texture Mapping */
44 
45 #define TEXTURE_MAPPING_DEFINE(TextureNode) \
46  SOCKET_POINT(tex_mapping.translation, "Translation", zero_float3()); \
47  SOCKET_VECTOR(tex_mapping.rotation, "Rotation", zero_float3()); \
48  SOCKET_VECTOR(tex_mapping.scale, "Scale", one_float3()); \
49 \
50  SOCKET_VECTOR(tex_mapping.min, "Min", make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX)); \
51  SOCKET_VECTOR(tex_mapping.max, "Max", make_float3(FLT_MAX, FLT_MAX, FLT_MAX)); \
52  SOCKET_BOOLEAN(tex_mapping.use_minmax, "Use Min Max", false); \
53 \
54  static NodeEnum mapping_axis_enum; \
55  mapping_axis_enum.insert("none", TextureMapping::NONE); \
56  mapping_axis_enum.insert("x", TextureMapping::X); \
57  mapping_axis_enum.insert("y", TextureMapping::Y); \
58  mapping_axis_enum.insert("z", TextureMapping::Z); \
59  SOCKET_ENUM(tex_mapping.x_mapping, "x_mapping", mapping_axis_enum, TextureMapping::X); \
60  SOCKET_ENUM(tex_mapping.y_mapping, "y_mapping", mapping_axis_enum, TextureMapping::Y); \
61  SOCKET_ENUM(tex_mapping.z_mapping, "z_mapping", mapping_axis_enum, TextureMapping::Z); \
62 \
63  static NodeEnum mapping_type_enum; \
64  mapping_type_enum.insert("point", TextureMapping::POINT); \
65  mapping_type_enum.insert("texture", TextureMapping::TEXTURE); \
66  mapping_type_enum.insert("vector", TextureMapping::VECTOR); \
67  mapping_type_enum.insert("normal", TextureMapping::NORMAL); \
68  SOCKET_ENUM(tex_mapping.type, "Type", mapping_type_enum, TextureMapping::TEXTURE); \
69 \
70  static NodeEnum mapping_projection_enum; \
71  mapping_projection_enum.insert("flat", TextureMapping::FLAT); \
72  mapping_projection_enum.insert("cube", TextureMapping::CUBE); \
73  mapping_projection_enum.insert("tube", TextureMapping::TUBE); \
74  mapping_projection_enum.insert("sphere", TextureMapping::SPHERE); \
75  SOCKET_ENUM(tex_mapping.projection, "Projection", mapping_projection_enum, TextureMapping::FLAT);
76 
78 {
79 }
80 
82 {
84 
85  if (x_mapping != NONE)
86  mmat[0][x_mapping - 1] = 1.0f;
87  if (y_mapping != NONE)
88  mmat[1][y_mapping - 1] = 1.0f;
89  if (z_mapping != NONE)
90  mmat[2][z_mapping - 1] = 1.0f;
91 
92  float3 scale_clamped = scale;
93 
94  if (type == TEXTURE || type == NORMAL) {
95  /* keep matrix invertible */
96  if (fabsf(scale.x) < 1e-5f)
97  scale_clamped.x = signf(scale.x) * 1e-5f;
98  if (fabsf(scale.y) < 1e-5f)
99  scale_clamped.y = signf(scale.y) * 1e-5f;
100  if (fabsf(scale.z) < 1e-5f)
101  scale_clamped.z = signf(scale.z) * 1e-5f;
102  }
103 
104  Transform smat = transform_scale(scale_clamped);
107 
108  Transform mat;
109 
110  switch (type) {
111  case TEXTURE:
112  /* inverse transform on texture coordinate gives
113  * forward transform on texture */
114  mat = tmat * rmat * smat;
115  mat = transform_inverse(mat);
116  break;
117  case POINT:
118  /* full transform */
119  mat = tmat * rmat * smat;
120  break;
121  case VECTOR:
122  /* no translation for vectors */
123  mat = rmat * smat;
124  break;
125  case NORMAL:
126  /* no translation for normals, and inverse transpose */
127  mat = rmat * smat;
128  mat = transform_transposed_inverse(mat);
129  break;
130  }
131 
132  /* projection last */
133  mat = mat * mmat;
134 
135  return mat;
136 }
137 
139 {
140  if (translation != zero_float3())
141  return false;
142  if (rotation != zero_float3())
143  return false;
144  if (scale != one_float3())
145  return false;
146 
147  if (x_mapping != X || y_mapping != Y || z_mapping != Z)
148  return false;
149  if (use_minmax)
150  return false;
151 
152  return true;
153 }
154 
155 void TextureMapping::compile(SVMCompiler &compiler, int offset_in, int offset_out)
156 {
157  compiler.add_node(NODE_TEXTURE_MAPPING, offset_in, offset_out);
158 
160  compiler.add_node(tfm.x);
161  compiler.add_node(tfm.y);
162  compiler.add_node(tfm.z);
163 
164  if (use_minmax) {
165  compiler.add_node(NODE_MIN_MAX, offset_out, offset_out);
166  compiler.add_node(float3_to_float4(min));
167  compiler.add_node(float3_to_float4(max));
168  }
169 
170  if (type == NORMAL) {
171  compiler.add_node(NODE_VECTOR_MATH,
173  compiler.encode_uchar4(offset_out, offset_out, offset_out),
174  compiler.encode_uchar4(SVM_STACK_INVALID, offset_out));
175  }
176 }
177 
178 /* Convenience function for texture nodes, allocating stack space to output
179  * a modified vector and returning its offset */
181 {
182  if (!skip()) {
183  int offset_in = compiler.stack_assign(vector_in);
184  int offset_out = compiler.stack_find_offset(SocketType::VECTOR);
185 
186  compile(compiler, offset_in, offset_out);
187 
188  return offset_out;
189  }
190 
191  return compiler.stack_assign(vector_in);
192 }
193 
194 void TextureMapping::compile_end(SVMCompiler &compiler, ShaderInput *vector_in, int vector_offset)
195 {
196  if (!skip()) {
197  compiler.stack_clear_offset(vector_in->type(), vector_offset);
198  }
199 }
200 
202 {
203  if (!skip()) {
204  compiler.parameter("mapping", compute_transform());
205  compiler.parameter("use_mapping", 1);
206  }
207 }
208 
209 /* Image Texture */
210 
212 {
213  NodeType *type = NodeType::add("image_texture", create, NodeType::SHADER);
214 
216 
217  SOCKET_STRING(filename, "Filename", ustring());
218  SOCKET_STRING(colorspace, "Colorspace", u_colorspace_auto);
219 
220  static NodeEnum alpha_type_enum;
221  alpha_type_enum.insert("auto", IMAGE_ALPHA_AUTO);
222  alpha_type_enum.insert("unassociated", IMAGE_ALPHA_UNASSOCIATED);
223  alpha_type_enum.insert("associated", IMAGE_ALPHA_ASSOCIATED);
224  alpha_type_enum.insert("channel_packed", IMAGE_ALPHA_CHANNEL_PACKED);
225  alpha_type_enum.insert("ignore", IMAGE_ALPHA_IGNORE);
226  SOCKET_ENUM(alpha_type, "Alpha Type", alpha_type_enum, IMAGE_ALPHA_AUTO);
227 
228  static NodeEnum interpolation_enum;
229  interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
230  interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
231  interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
232  interpolation_enum.insert("smart", INTERPOLATION_SMART);
233  SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
234 
235  static NodeEnum extension_enum;
236  extension_enum.insert("periodic", EXTENSION_REPEAT);
237  extension_enum.insert("clamp", EXTENSION_EXTEND);
238  extension_enum.insert("black", EXTENSION_CLIP);
239  SOCKET_ENUM(extension, "Extension", extension_enum, EXTENSION_REPEAT);
240 
241  static NodeEnum projection_enum;
242  projection_enum.insert("flat", NODE_IMAGE_PROJ_FLAT);
243  projection_enum.insert("box", NODE_IMAGE_PROJ_BOX);
244  projection_enum.insert("sphere", NODE_IMAGE_PROJ_SPHERE);
245  projection_enum.insert("tube", NODE_IMAGE_PROJ_TUBE);
246  SOCKET_ENUM(projection, "Projection", projection_enum, NODE_IMAGE_PROJ_FLAT);
247 
248  SOCKET_FLOAT(projection_blend, "Projection Blend", 0.0f);
249 
250  SOCKET_INT_ARRAY(tiles, "Tiles", array<int>());
251  SOCKET_BOOLEAN(animated, "Animated", false);
252 
254 
255  SOCKET_OUT_COLOR(color, "Color");
256  SOCKET_OUT_FLOAT(alpha, "Alpha");
257 
258  return type;
259 }
260 
261 ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(get_node_type())
262 {
263  colorspace = u_colorspace_raw;
264  animated = false;
265  tiles.push_back_slow(1001);
266 }
267 
269 {
270  ImageTextureNode *node = graph->create_node<ImageTextureNode>(*this);
271  node->handle = handle;
272  return node;
273 }
274 
276 {
278  params.animated = animated;
279  params.interpolation = interpolation;
280  params.extension = extension;
281  params.alpha_type = alpha_type;
282  params.colorspace = colorspace;
283  return params;
284 }
285 
287 {
288  /* Box projection computes its own UVs that always lie in the
289  * 1001 tile, so there's no point in loading any others. */
290  if (projection == NODE_IMAGE_PROJ_BOX) {
291  tiles.clear();
292  tiles.push_back_slow(1001);
293  return;
294  }
295 
296  if (!scene->params.background) {
297  /* During interactive renders, all tiles are loaded.
298  * While we could support updating this when UVs change, that could lead
299  * to annoying interruptions when loading images while editing UVs. */
300  return;
301  }
302 
303  /* Only check UVs for tile culling if there are multiple tiles. */
304  if (tiles.size() < 2) {
305  return;
306  }
307 
308  ShaderInput *vector_in = input("Vector");
309  ustring attribute;
310  if (vector_in->link) {
311  ShaderNode *node = vector_in->link->parent;
312  if (node->type == UVMapNode::get_node_type()) {
313  UVMapNode *uvmap = (UVMapNode *)node;
314  attribute = uvmap->get_attribute();
315  }
316  else if (node->type == TextureCoordinateNode::get_node_type()) {
317  if (vector_in->link != node->output("UV")) {
318  return;
319  }
320  }
321  else {
322  return;
323  }
324  }
325 
326  unordered_set<int> used_tiles;
327  /* TODO(lukas): This is quite inefficient. A fairly simple improvement would
328  * be to have a cache in each mesh that is indexed by attribute.
329  * Additionally, building a graph-to-meshes list once could help. */
330  foreach (Geometry *geom, scene->geometry) {
331  foreach (Node *node, geom->get_used_shaders()) {
332  Shader *shader = static_cast<Shader *>(node);
333  if (shader->graph == graph) {
334  geom->get_uv_tiles(attribute, used_tiles);
335  }
336  }
337  }
338 
339  array<int> new_tiles;
340  foreach (int tile, tiles) {
341  if (used_tiles.count(tile)) {
342  new_tiles.push_back_slow(tile);
343  }
344  }
345  tiles.steal_data(new_tiles);
346 }
347 
349 {
350 #ifdef WITH_PTEX
351  /* todo: avoid loading other texture coordinates when using ptex,
352  * and hide texture coordinate socket in the UI */
353  if (shader->has_surface && string_endswith(filename, ".ptx")) {
354  /* ptex */
357  }
358 #endif
359 
361 }
362 
364 {
365  ShaderInput *vector_in = input("Vector");
366  ShaderOutput *color_out = output("Color");
367  ShaderOutput *alpha_out = output("Alpha");
368 
369  if (handle.empty()) {
370  cull_tiles(compiler.scene, compiler.current_graph);
371  ImageManager *image_manager = compiler.scene->image_manager;
372  handle = image_manager->add_image(filename.string(), image_params(), tiles);
373  }
374 
375  /* All tiles have the same metadata. */
376  const ImageMetaData metadata = handle.metadata();
377  const bool compress_as_srgb = metadata.compress_as_srgb;
378  const ustring known_colorspace = metadata.colorspace;
379 
380  int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
381  uint flags = 0;
382 
383  if (compress_as_srgb) {
385  }
386  if (!alpha_out->links.empty()) {
387  const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
388  alpha_type == IMAGE_ALPHA_CHANNEL_PACKED ||
389  alpha_type == IMAGE_ALPHA_IGNORE);
390 
391  if (unassociate_alpha) {
393  }
394  }
395 
396  if (projection != NODE_IMAGE_PROJ_BOX) {
397  /* If there only is one image (a very common case), we encode it as a negative value. */
398  int num_nodes;
399  if (handle.num_tiles() == 1) {
400  num_nodes = -handle.svm_slot();
401  }
402  else {
403  num_nodes = divide_up(handle.num_tiles(), 2);
404  }
405 
406  compiler.add_node(NODE_TEX_IMAGE,
407  num_nodes,
408  compiler.encode_uchar4(vector_offset,
409  compiler.stack_assign_if_linked(color_out),
410  compiler.stack_assign_if_linked(alpha_out),
411  flags),
412  projection);
413 
414  if (num_nodes > 0) {
415  for (int i = 0; i < num_nodes; i++) {
416  int4 node;
417  node.x = tiles[2 * i];
418  node.y = handle.svm_slot(2 * i);
419  if (2 * i + 1 < tiles.size()) {
420  node.z = tiles[2 * i + 1];
421  node.w = handle.svm_slot(2 * i + 1);
422  }
423  else {
424  node.z = -1;
425  node.w = -1;
426  }
427  compiler.add_node(node.x, node.y, node.z, node.w);
428  }
429  }
430  }
431  else {
432  assert(handle.num_tiles() == 1);
433  compiler.add_node(NODE_TEX_IMAGE_BOX,
434  handle.svm_slot(),
435  compiler.encode_uchar4(vector_offset,
436  compiler.stack_assign_if_linked(color_out),
437  compiler.stack_assign_if_linked(alpha_out),
438  flags),
439  __float_as_int(projection_blend));
440  }
441 
442  tex_mapping.compile_end(compiler, vector_in, vector_offset);
443 }
444 
446 {
447  ShaderOutput *alpha_out = output("Alpha");
448 
449  tex_mapping.compile(compiler);
450 
451  if (handle.empty()) {
452  ImageManager *image_manager = compiler.scene->image_manager;
453  handle = image_manager->add_image(filename.string(), image_params());
454  }
455 
456  const ImageMetaData metadata = handle.metadata();
457  const bool is_float = metadata.is_float();
458  const bool compress_as_srgb = metadata.compress_as_srgb;
459  const ustring known_colorspace = metadata.colorspace;
460 
461  if (handle.svm_slot() == -1) {
462  compiler.parameter_texture(
463  "filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
464  }
465  else {
466  compiler.parameter_texture("filename", handle.svm_slot());
467  }
468 
469  const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
470  alpha_type == IMAGE_ALPHA_CHANNEL_PACKED ||
471  alpha_type == IMAGE_ALPHA_IGNORE);
472  const bool is_tiled = (filename.find("<UDIM>") != string::npos);
473 
474  compiler.parameter(this, "projection");
475  compiler.parameter(this, "projection_blend");
476  compiler.parameter("compress_as_srgb", compress_as_srgb);
477  compiler.parameter("ignore_alpha", alpha_type == IMAGE_ALPHA_IGNORE);
478  compiler.parameter("unassociate_alpha", !alpha_out->links.empty() && unassociate_alpha);
479  compiler.parameter("is_float", is_float);
480  compiler.parameter("is_tiled", is_tiled);
481  compiler.parameter(this, "interpolation");
482  compiler.parameter(this, "extension");
483 
484  compiler.add(this, "node_image_texture");
485 }
486 
487 /* Environment Texture */
488 
490 {
491  NodeType *type = NodeType::add("environment_texture", create, NodeType::SHADER);
492 
494 
495  SOCKET_STRING(filename, "Filename", ustring());
496  SOCKET_STRING(colorspace, "Colorspace", u_colorspace_auto);
497 
498  static NodeEnum alpha_type_enum;
499  alpha_type_enum.insert("auto", IMAGE_ALPHA_AUTO);
500  alpha_type_enum.insert("unassociated", IMAGE_ALPHA_UNASSOCIATED);
501  alpha_type_enum.insert("associated", IMAGE_ALPHA_ASSOCIATED);
502  alpha_type_enum.insert("channel_packed", IMAGE_ALPHA_CHANNEL_PACKED);
503  alpha_type_enum.insert("ignore", IMAGE_ALPHA_IGNORE);
504  SOCKET_ENUM(alpha_type, "Alpha Type", alpha_type_enum, IMAGE_ALPHA_AUTO);
505 
506  static NodeEnum interpolation_enum;
507  interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
508  interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
509  interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
510  interpolation_enum.insert("smart", INTERPOLATION_SMART);
511  SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
512 
513  static NodeEnum projection_enum;
514  projection_enum.insert("equirectangular", NODE_ENVIRONMENT_EQUIRECTANGULAR);
515  projection_enum.insert("mirror_ball", NODE_ENVIRONMENT_MIRROR_BALL);
516  SOCKET_ENUM(projection, "Projection", projection_enum, NODE_ENVIRONMENT_EQUIRECTANGULAR);
517 
518  SOCKET_BOOLEAN(animated, "Animated", false);
519 
521 
522  SOCKET_OUT_COLOR(color, "Color");
523  SOCKET_OUT_FLOAT(alpha, "Alpha");
524 
525  return type;
526 }
527 
528 EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode(get_node_type())
529 {
530  colorspace = u_colorspace_raw;
531  animated = false;
532 }
533 
535 {
537  node->handle = handle;
538  return node;
539 }
540 
542 {
544  params.animated = animated;
545  params.interpolation = interpolation;
546  params.extension = EXTENSION_REPEAT;
547  params.alpha_type = alpha_type;
548  params.colorspace = colorspace;
549  return params;
550 }
551 
553 {
554 #ifdef WITH_PTEX
555  if (shader->has_surface && string_endswith(filename, ".ptx")) {
556  /* ptex */
559  }
560 #endif
561 
563 }
564 
566 {
567  ShaderInput *vector_in = input("Vector");
568  ShaderOutput *color_out = output("Color");
569  ShaderOutput *alpha_out = output("Alpha");
570 
571  if (handle.empty()) {
572  ImageManager *image_manager = compiler.scene->image_manager;
573  handle = image_manager->add_image(filename.string(), image_params());
574  }
575 
576  const ImageMetaData metadata = handle.metadata();
577  const bool compress_as_srgb = metadata.compress_as_srgb;
578  const ustring known_colorspace = metadata.colorspace;
579 
580  int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
581  uint flags = 0;
582 
583  if (compress_as_srgb) {
585  }
586 
588  handle.svm_slot(),
589  compiler.encode_uchar4(vector_offset,
590  compiler.stack_assign_if_linked(color_out),
591  compiler.stack_assign_if_linked(alpha_out),
592  flags),
593  projection);
594 
595  tex_mapping.compile_end(compiler, vector_in, vector_offset);
596 }
597 
599 {
600  if (handle.empty()) {
601  ImageManager *image_manager = compiler.scene->image_manager;
602  handle = image_manager->add_image(filename.string(), image_params());
603  }
604 
605  tex_mapping.compile(compiler);
606 
607  const ImageMetaData metadata = handle.metadata();
608  const bool is_float = metadata.is_float();
609  const bool compress_as_srgb = metadata.compress_as_srgb;
610  const ustring known_colorspace = metadata.colorspace;
611 
612  if (handle.svm_slot() == -1) {
613  compiler.parameter_texture(
614  "filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
615  }
616  else {
617  compiler.parameter_texture("filename", handle.svm_slot());
618  }
619 
620  compiler.parameter(this, "projection");
621  compiler.parameter(this, "interpolation");
622  compiler.parameter("compress_as_srgb", compress_as_srgb);
623  compiler.parameter("ignore_alpha", alpha_type == IMAGE_ALPHA_IGNORE);
624  compiler.parameter("is_float", is_float);
625  compiler.add(this, "node_environment_texture");
626 }
627 
628 /* Sky Texture */
629 
631 {
632  return make_float2(acosf(dir.z), atan2f(dir.x, dir.y));
633 }
634 
635 typedef struct SunSky {
636  /* sun direction in spherical and cartesian */
637  float theta, phi;
638 
639  /* Parameter */
641  float config_x[9], config_y[9], config_z[9], nishita_data[10];
643 
644 /* Preetham model */
645 static float sky_perez_function(float lam[6], float theta, float gamma)
646 {
647  return (1.0f + lam[0] * expf(lam[1] / cosf(theta))) *
648  (1.0f + lam[2] * expf(lam[3] * gamma) + lam[4] * cosf(gamma) * cosf(gamma));
649 }
650 
651 static void sky_texture_precompute_preetham(SunSky *sunsky, float3 dir, float turbidity)
652 {
653  /*
654  * We re-use the SunSky struct of the new model, to avoid extra variables
655  * zenith_Y/x/y is now radiance_x/y/z
656  * perez_Y/x/y is now config_x/y/z
657  */
658 
659  float2 spherical = sky_spherical_coordinates(dir);
660  float theta = spherical.x;
661  float phi = spherical.y;
662 
663  sunsky->theta = theta;
664  sunsky->phi = phi;
665 
666  float theta2 = theta * theta;
667  float theta3 = theta2 * theta;
668  float T = turbidity;
669  float T2 = T * T;
670 
671  float chi = (4.0f / 9.0f - T / 120.0f) * (M_PI_F - 2.0f * theta);
672  sunsky->radiance_x = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f;
673  sunsky->radiance_x *= 0.06f;
674 
675  sunsky->radiance_y = (0.00166f * theta3 - 0.00375f * theta2 + 0.00209f * theta) * T2 +
676  (-0.02903f * theta3 + 0.06377f * theta2 - 0.03202f * theta + 0.00394f) * T +
677  (0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * theta + 0.25886f);
678 
679  sunsky->radiance_z = (0.00275f * theta3 - 0.00610f * theta2 + 0.00317f * theta) * T2 +
680  (-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * theta + 0.00516f) * T +
681  (0.15346f * theta3 - 0.26756f * theta2 + 0.06670f * theta + 0.26688f);
682 
683  sunsky->config_x[0] = (0.1787f * T - 1.4630f);
684  sunsky->config_x[1] = (-0.3554f * T + 0.4275f);
685  sunsky->config_x[2] = (-0.0227f * T + 5.3251f);
686  sunsky->config_x[3] = (0.1206f * T - 2.5771f);
687  sunsky->config_x[4] = (-0.0670f * T + 0.3703f);
688 
689  sunsky->config_y[0] = (-0.0193f * T - 0.2592f);
690  sunsky->config_y[1] = (-0.0665f * T + 0.0008f);
691  sunsky->config_y[2] = (-0.0004f * T + 0.2125f);
692  sunsky->config_y[3] = (-0.0641f * T - 0.8989f);
693  sunsky->config_y[4] = (-0.0033f * T + 0.0452f);
694 
695  sunsky->config_z[0] = (-0.0167f * T - 0.2608f);
696  sunsky->config_z[1] = (-0.0950f * T + 0.0092f);
697  sunsky->config_z[2] = (-0.0079f * T + 0.2102f);
698  sunsky->config_z[3] = (-0.0441f * T - 1.6537f);
699  sunsky->config_z[4] = (-0.0109f * T + 0.0529f);
700 
701  /* unused for old sky model */
702  for (int i = 5; i < 9; i++) {
703  sunsky->config_x[i] = 0.0f;
704  sunsky->config_y[i] = 0.0f;
705  sunsky->config_z[i] = 0.0f;
706  }
707 
708  sunsky->radiance_x /= sky_perez_function(sunsky->config_x, 0, theta);
709  sunsky->radiance_y /= sky_perez_function(sunsky->config_y, 0, theta);
710  sunsky->radiance_z /= sky_perez_function(sunsky->config_z, 0, theta);
711 }
712 
713 /* Hosek / Wilkie */
715  float3 dir,
716  float turbidity,
717  float ground_albedo)
718 {
719  /* Calculate Sun Direction and save coordinates */
720  float2 spherical = sky_spherical_coordinates(dir);
721  float theta = spherical.x;
722  float phi = spherical.y;
723 
724  /* Clamp Turbidity */
725  turbidity = clamp(turbidity, 0.0f, 10.0f);
726 
727  /* Clamp to Horizon */
728  theta = clamp(theta, 0.0f, M_PI_2_F);
729 
730  sunsky->theta = theta;
731  sunsky->phi = phi;
732 
733  float solarElevation = M_PI_2_F - theta;
734 
735  /* Initialize Sky Model */
736  SKY_ArHosekSkyModelState *sky_state;
738  (double)turbidity, (double)ground_albedo, (double)solarElevation);
739 
740  /* Copy values from sky_state to SunSky */
741  for (int i = 0; i < 9; ++i) {
742  sunsky->config_x[i] = (float)sky_state->configs[0][i];
743  sunsky->config_y[i] = (float)sky_state->configs[1][i];
744  sunsky->config_z[i] = (float)sky_state->configs[2][i];
745  }
746  sunsky->radiance_x = (float)sky_state->radiances[0];
747  sunsky->radiance_y = (float)sky_state->radiances[1];
748  sunsky->radiance_z = (float)sky_state->radiances[2];
749 
750  /* Free sky_state */
752 }
753 
754 /* Nishita improved */
756  bool sun_disc,
757  float sun_size,
758  float sun_intensity,
759  float sun_elevation,
760  float sun_rotation,
761  float altitude,
762  float air_density,
763  float dust_density)
764 {
765  /* sample 2 sun pixels */
766  float pixel_bottom[3];
767  float pixel_top[3];
769  sun_elevation, sun_size, altitude, air_density, dust_density, pixel_bottom, pixel_top);
770  /* limit sun rotation between 0 and 360 degrees */
771  sun_rotation = fmodf(sun_rotation, M_2PI_F);
772  if (sun_rotation < 0.0f) {
773  sun_rotation += M_2PI_F;
774  }
775  sun_rotation = M_2PI_F - sun_rotation;
776  /* send data to svm_sky */
777  sunsky->nishita_data[0] = pixel_bottom[0];
778  sunsky->nishita_data[1] = pixel_bottom[1];
779  sunsky->nishita_data[2] = pixel_bottom[2];
780  sunsky->nishita_data[3] = pixel_top[0];
781  sunsky->nishita_data[4] = pixel_top[1];
782  sunsky->nishita_data[5] = pixel_top[2];
783  sunsky->nishita_data[6] = sun_elevation;
784  sunsky->nishita_data[7] = sun_rotation;
785  sunsky->nishita_data[8] = sun_disc ? sun_size : -1.0f;
786  sunsky->nishita_data[9] = sun_intensity;
787 }
788 
790 {
791  NodeType *type = NodeType::add("sky_texture", create, NodeType::SHADER);
792 
794 
795  static NodeEnum type_enum;
796  type_enum.insert("preetham", NODE_SKY_PREETHAM);
797  type_enum.insert("hosek_wilkie", NODE_SKY_HOSEK);
798  type_enum.insert("nishita_improved", NODE_SKY_NISHITA);
799  SOCKET_ENUM(sky_type, "Type", type_enum, NODE_SKY_NISHITA);
800 
801  SOCKET_VECTOR(sun_direction, "Sun Direction", make_float3(0.0f, 0.0f, 1.0f));
802  SOCKET_FLOAT(turbidity, "Turbidity", 2.2f);
803  SOCKET_FLOAT(ground_albedo, "Ground Albedo", 0.3f);
804  SOCKET_BOOLEAN(sun_disc, "Sun Disc", true);
805  SOCKET_FLOAT(sun_size, "Sun Size", 0.009512f);
806  SOCKET_FLOAT(sun_intensity, "Sun Intensity", 1.0f);
807  SOCKET_FLOAT(sun_elevation, "Sun Elevation", 15.0f * M_PI_F / 180.0f);
808  SOCKET_FLOAT(sun_rotation, "Sun Rotation", 0.0f);
809  SOCKET_FLOAT(altitude, "Altitude", 1.0f);
810  SOCKET_FLOAT(air_density, "Air", 1.0f);
811  SOCKET_FLOAT(dust_density, "Dust", 1.0f);
812  SOCKET_FLOAT(ozone_density, "Ozone", 1.0f);
813 
815 
816  SOCKET_OUT_COLOR(color, "Color");
817 
818  return type;
819 }
820 
821 SkyTextureNode::SkyTextureNode() : TextureNode(get_node_type())
822 {
823 }
824 
825 void SkyTextureNode::compile(SVMCompiler &compiler)
826 {
827  ShaderInput *vector_in = input("Vector");
828  ShaderOutput *color_out = output("Color");
829 
830  SunSky sunsky;
831  if (sky_type == NODE_SKY_PREETHAM)
832  sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
833  else if (sky_type == NODE_SKY_HOSEK)
834  sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
835  else if (sky_type == NODE_SKY_NISHITA) {
836  /* Clamp altitude to reasonable values.
837  * Below 1m causes numerical issues and above 60km is space. */
838  float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
839 
841  sun_disc,
842  get_sun_size(),
843  sun_intensity,
844  sun_elevation,
845  sun_rotation,
846  clamped_altitude,
847  air_density,
848  dust_density);
849  /* precomputed texture image parameters */
850  ImageManager *image_manager = compiler.scene->image_manager;
851  ImageParams impar;
853  impar.extension = EXTENSION_EXTEND;
854 
855  /* precompute sky texture */
856  if (handle.empty()) {
857  SkyLoader *loader = new SkyLoader(
858  sun_elevation, clamped_altitude, air_density, dust_density, ozone_density);
859  handle = image_manager->add_image(loader, impar);
860  }
861  }
862  else
863  assert(false);
864 
865  int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
866 
867  compiler.stack_assign(color_out);
868  compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), sky_type);
869  /* nishita doesn't need this data */
870  if (sky_type != NODE_SKY_NISHITA) {
871  compiler.add_node(__float_as_uint(sunsky.phi),
872  __float_as_uint(sunsky.theta),
873  __float_as_uint(sunsky.radiance_x),
874  __float_as_uint(sunsky.radiance_y));
875  compiler.add_node(__float_as_uint(sunsky.radiance_z),
876  __float_as_uint(sunsky.config_x[0]),
877  __float_as_uint(sunsky.config_x[1]),
878  __float_as_uint(sunsky.config_x[2]));
879  compiler.add_node(__float_as_uint(sunsky.config_x[3]),
880  __float_as_uint(sunsky.config_x[4]),
881  __float_as_uint(sunsky.config_x[5]),
882  __float_as_uint(sunsky.config_x[6]));
883  compiler.add_node(__float_as_uint(sunsky.config_x[7]),
884  __float_as_uint(sunsky.config_x[8]),
885  __float_as_uint(sunsky.config_y[0]),
886  __float_as_uint(sunsky.config_y[1]));
887  compiler.add_node(__float_as_uint(sunsky.config_y[2]),
888  __float_as_uint(sunsky.config_y[3]),
889  __float_as_uint(sunsky.config_y[4]),
890  __float_as_uint(sunsky.config_y[5]));
891  compiler.add_node(__float_as_uint(sunsky.config_y[6]),
892  __float_as_uint(sunsky.config_y[7]),
893  __float_as_uint(sunsky.config_y[8]),
894  __float_as_uint(sunsky.config_z[0]));
895  compiler.add_node(__float_as_uint(sunsky.config_z[1]),
896  __float_as_uint(sunsky.config_z[2]),
897  __float_as_uint(sunsky.config_z[3]),
898  __float_as_uint(sunsky.config_z[4]));
899  compiler.add_node(__float_as_uint(sunsky.config_z[5]),
900  __float_as_uint(sunsky.config_z[6]),
901  __float_as_uint(sunsky.config_z[7]),
902  __float_as_uint(sunsky.config_z[8]));
903  }
904  else {
905  compiler.add_node(__float_as_uint(sunsky.nishita_data[0]),
906  __float_as_uint(sunsky.nishita_data[1]),
907  __float_as_uint(sunsky.nishita_data[2]),
908  __float_as_uint(sunsky.nishita_data[3]));
909  compiler.add_node(__float_as_uint(sunsky.nishita_data[4]),
910  __float_as_uint(sunsky.nishita_data[5]),
911  __float_as_uint(sunsky.nishita_data[6]),
912  __float_as_uint(sunsky.nishita_data[7]));
913  compiler.add_node(__float_as_uint(sunsky.nishita_data[8]),
914  __float_as_uint(sunsky.nishita_data[9]),
915  handle.svm_slot(),
916  0);
917  }
918 
919  tex_mapping.compile_end(compiler, vector_in, vector_offset);
920 }
921 
922 void SkyTextureNode::compile(OSLCompiler &compiler)
923 {
924  tex_mapping.compile(compiler);
925 
926  SunSky sunsky;
927  if (sky_type == NODE_SKY_PREETHAM)
928  sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity);
929  else if (sky_type == NODE_SKY_HOSEK)
930  sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo);
931  else if (sky_type == NODE_SKY_NISHITA) {
932  /* Clamp altitude to reasonable values.
933  * Below 1m causes numerical issues and above 60km is space. */
934  float clamped_altitude = clamp(altitude, 1.0f, 59999.0f);
935 
937  sun_disc,
938  get_sun_size(),
939  sun_intensity,
940  sun_elevation,
941  sun_rotation,
942  clamped_altitude,
943  air_density,
944  dust_density);
945  /* precomputed texture image parameters */
946  ImageManager *image_manager = compiler.scene->image_manager;
947  ImageParams impar;
949  impar.extension = EXTENSION_EXTEND;
950 
951  /* precompute sky texture */
952  if (handle.empty()) {
953  SkyLoader *loader = new SkyLoader(
954  sun_elevation, clamped_altitude, air_density, dust_density, ozone_density);
955  handle = image_manager->add_image(loader, impar);
956  }
957  }
958  else
959  assert(false);
960 
961  compiler.parameter(this, "sky_type");
962  compiler.parameter("theta", sunsky.theta);
963  compiler.parameter("phi", sunsky.phi);
964  compiler.parameter_color("radiance",
965  make_float3(sunsky.radiance_x, sunsky.radiance_y, sunsky.radiance_z));
966  compiler.parameter_array("config_x", sunsky.config_x, 9);
967  compiler.parameter_array("config_y", sunsky.config_y, 9);
968  compiler.parameter_array("config_z", sunsky.config_z, 9);
969  compiler.parameter_array("nishita_data", sunsky.nishita_data, 10);
970  /* nishita texture */
971  if (sky_type == NODE_SKY_NISHITA) {
972  compiler.parameter_texture("filename", handle.svm_slot());
973  }
974  compiler.add(this, "node_sky_texture");
975 }
976 
977 /* Gradient Texture */
978 
980 {
981  NodeType *type = NodeType::add("gradient_texture", create, NodeType::SHADER);
982 
984 
985  static NodeEnum type_enum;
986  type_enum.insert("linear", NODE_BLEND_LINEAR);
987  type_enum.insert("quadratic", NODE_BLEND_QUADRATIC);
988  type_enum.insert("easing", NODE_BLEND_EASING);
989  type_enum.insert("diagonal", NODE_BLEND_DIAGONAL);
990  type_enum.insert("radial", NODE_BLEND_RADIAL);
991  type_enum.insert("quadratic_sphere", NODE_BLEND_QUADRATIC_SPHERE);
992  type_enum.insert("spherical", NODE_BLEND_SPHERICAL);
993  SOCKET_ENUM(gradient_type, "Type", type_enum, NODE_BLEND_LINEAR);
994 
996 
997  SOCKET_OUT_COLOR(color, "Color");
998  SOCKET_OUT_FLOAT(fac, "Fac");
999 
1000  return type;
1001 }
1002 
1003 GradientTextureNode::GradientTextureNode() : TextureNode(get_node_type())
1004 {
1005 }
1006 
1008 {
1009  ShaderInput *vector_in = input("Vector");
1010  ShaderOutput *color_out = output("Color");
1011  ShaderOutput *fac_out = output("Fac");
1012 
1013  int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1014 
1015  compiler.add_node(NODE_TEX_GRADIENT,
1016  compiler.encode_uchar4(gradient_type,
1017  vector_offset,
1018  compiler.stack_assign_if_linked(fac_out),
1019  compiler.stack_assign_if_linked(color_out)));
1020 
1021  tex_mapping.compile_end(compiler, vector_in, vector_offset);
1022 }
1023 
1025 {
1026  tex_mapping.compile(compiler);
1027 
1028  compiler.parameter(this, "gradient_type");
1029  compiler.add(this, "node_gradient_texture");
1030 }
1031 
1032 /* Noise Texture */
1033 
1035 {
1036  NodeType *type = NodeType::add("noise_texture", create, NodeType::SHADER);
1037 
1039 
1040  static NodeEnum dimensions_enum;
1041  dimensions_enum.insert("1D", 1);
1042  dimensions_enum.insert("2D", 2);
1043  dimensions_enum.insert("3D", 3);
1044  dimensions_enum.insert("4D", 4);
1045  SOCKET_ENUM(dimensions, "Dimensions", dimensions_enum, 3);
1046 
1048  SOCKET_IN_FLOAT(w, "W", 0.0f);
1049  SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
1050  SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
1051  SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
1052  SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f);
1053 
1054  SOCKET_OUT_FLOAT(fac, "Fac");
1055  SOCKET_OUT_COLOR(color, "Color");
1056 
1057  return type;
1058 }
1059 
1060 NoiseTextureNode::NoiseTextureNode() : TextureNode(get_node_type())
1061 {
1062 }
1063 
1064 void NoiseTextureNode::compile(SVMCompiler &compiler)
1065 {
1066  ShaderInput *vector_in = input("Vector");
1067  ShaderInput *w_in = input("W");
1068  ShaderInput *scale_in = input("Scale");
1069  ShaderInput *detail_in = input("Detail");
1070  ShaderInput *roughness_in = input("Roughness");
1071  ShaderInput *distortion_in = input("Distortion");
1072  ShaderOutput *fac_out = output("Fac");
1073  ShaderOutput *color_out = output("Color");
1074 
1075  int vector_stack_offset = tex_mapping.compile_begin(compiler, vector_in);
1076  int w_stack_offset = compiler.stack_assign_if_linked(w_in);
1077  int scale_stack_offset = compiler.stack_assign_if_linked(scale_in);
1078  int detail_stack_offset = compiler.stack_assign_if_linked(detail_in);
1079  int roughness_stack_offset = compiler.stack_assign_if_linked(roughness_in);
1080  int distortion_stack_offset = compiler.stack_assign_if_linked(distortion_in);
1081  int fac_stack_offset = compiler.stack_assign_if_linked(fac_out);
1082  int color_stack_offset = compiler.stack_assign_if_linked(color_out);
1083 
1084  compiler.add_node(
1086  dimensions,
1087  compiler.encode_uchar4(
1088  vector_stack_offset, w_stack_offset, scale_stack_offset, detail_stack_offset),
1089  compiler.encode_uchar4(
1090  roughness_stack_offset, distortion_stack_offset, fac_stack_offset, color_stack_offset));
1091  compiler.add_node(
1093 
1094  compiler.add_node(
1096 
1097  tex_mapping.compile_end(compiler, vector_in, vector_stack_offset);
1098 }
1099 
1100 void NoiseTextureNode::compile(OSLCompiler &compiler)
1101 {
1102  tex_mapping.compile(compiler);
1103  compiler.parameter(this, "dimensions");
1104  compiler.add(this, "node_noise_texture");
1105 }
1106 
1107 /* Voronoi Texture */
1108 
1110 {
1111  NodeType *type = NodeType::add("voronoi_texture", create, NodeType::SHADER);
1112 
1114 
1115  static NodeEnum dimensions_enum;
1116  dimensions_enum.insert("1D", 1);
1117  dimensions_enum.insert("2D", 2);
1118  dimensions_enum.insert("3D", 3);
1119  dimensions_enum.insert("4D", 4);
1120  SOCKET_ENUM(dimensions, "Dimensions", dimensions_enum, 3);
1121 
1122  static NodeEnum metric_enum;
1123  metric_enum.insert("euclidean", NODE_VORONOI_EUCLIDEAN);
1124  metric_enum.insert("manhattan", NODE_VORONOI_MANHATTAN);
1125  metric_enum.insert("chebychev", NODE_VORONOI_CHEBYCHEV);
1126  metric_enum.insert("minkowski", NODE_VORONOI_MINKOWSKI);
1127  SOCKET_ENUM(metric, "Distance Metric", metric_enum, NODE_VORONOI_EUCLIDEAN);
1128 
1129  static NodeEnum feature_enum;
1130  feature_enum.insert("f1", NODE_VORONOI_F1);
1131  feature_enum.insert("f2", NODE_VORONOI_F2);
1132  feature_enum.insert("smooth_f1", NODE_VORONOI_SMOOTH_F1);
1133  feature_enum.insert("distance_to_edge", NODE_VORONOI_DISTANCE_TO_EDGE);
1134  feature_enum.insert("n_sphere_radius", NODE_VORONOI_N_SPHERE_RADIUS);
1135  SOCKET_ENUM(feature, "Feature", feature_enum, NODE_VORONOI_F1);
1136 
1138  SOCKET_IN_FLOAT(w, "W", 0.0f);
1139  SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
1140  SOCKET_IN_FLOAT(smoothness, "Smoothness", 5.0f);
1141  SOCKET_IN_FLOAT(exponent, "Exponent", 0.5f);
1142  SOCKET_IN_FLOAT(randomness, "Randomness", 1.0f);
1143 
1144  SOCKET_OUT_FLOAT(distance, "Distance");
1145  SOCKET_OUT_COLOR(color, "Color");
1146  SOCKET_OUT_POINT(position, "Position");
1147  SOCKET_OUT_FLOAT(w, "W");
1148  SOCKET_OUT_FLOAT(radius, "Radius");
1149 
1150  return type;
1151 }
1152 
1153 VoronoiTextureNode::VoronoiTextureNode() : TextureNode(get_node_type())
1154 {
1155 }
1156 
1158 {
1159  ShaderInput *vector_in = input("Vector");
1160  ShaderInput *w_in = input("W");
1161  ShaderInput *scale_in = input("Scale");
1162  ShaderInput *smoothness_in = input("Smoothness");
1163  ShaderInput *exponent_in = input("Exponent");
1164  ShaderInput *randomness_in = input("Randomness");
1165 
1166  ShaderOutput *distance_out = output("Distance");
1167  ShaderOutput *color_out = output("Color");
1168  ShaderOutput *position_out = output("Position");
1169  ShaderOutput *w_out = output("W");
1170  ShaderOutput *radius_out = output("Radius");
1171 
1172  int vector_stack_offset = tex_mapping.compile_begin(compiler, vector_in);
1173  int w_in_stack_offset = compiler.stack_assign_if_linked(w_in);
1174  int scale_stack_offset = compiler.stack_assign_if_linked(scale_in);
1175  int smoothness_stack_offset = compiler.stack_assign_if_linked(smoothness_in);
1176  int exponent_stack_offset = compiler.stack_assign_if_linked(exponent_in);
1177  int randomness_stack_offset = compiler.stack_assign_if_linked(randomness_in);
1178  int distance_stack_offset = compiler.stack_assign_if_linked(distance_out);
1179  int color_stack_offset = compiler.stack_assign_if_linked(color_out);
1180  int position_stack_offset = compiler.stack_assign_if_linked(position_out);
1181  int w_out_stack_offset = compiler.stack_assign_if_linked(w_out);
1182  int radius_stack_offset = compiler.stack_assign_if_linked(radius_out);
1183 
1184  compiler.add_node(NODE_TEX_VORONOI, dimensions, feature, metric);
1185  compiler.add_node(
1186  compiler.encode_uchar4(
1187  vector_stack_offset, w_in_stack_offset, scale_stack_offset, smoothness_stack_offset),
1188  compiler.encode_uchar4(exponent_stack_offset,
1189  randomness_stack_offset,
1190  distance_stack_offset,
1191  color_stack_offset),
1192  compiler.encode_uchar4(position_stack_offset, w_out_stack_offset, radius_stack_offset),
1193  __float_as_int(w));
1194 
1195  compiler.add_node(__float_as_int(scale),
1196  __float_as_int(smoothness),
1197  __float_as_int(exponent),
1198  __float_as_int(randomness));
1199 
1200  tex_mapping.compile_end(compiler, vector_in, vector_stack_offset);
1201 }
1202 
1204 {
1205  tex_mapping.compile(compiler);
1206 
1207  compiler.parameter(this, "dimensions");
1208  compiler.parameter(this, "feature");
1209  compiler.parameter(this, "metric");
1210  compiler.add(this, "node_voronoi_texture");
1211 }
1212 
1213 /* IES Light */
1214 
1216 {
1217  NodeType *type = NodeType::add("ies_light", create, NodeType::SHADER);
1218 
1220 
1221  SOCKET_STRING(ies, "IES", ustring());
1222  SOCKET_STRING(filename, "File Name", ustring());
1223 
1224  SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
1226 
1227  SOCKET_OUT_FLOAT(fac, "Fac");
1228 
1229  return type;
1230 }
1231 
1232 IESLightNode::IESLightNode() : TextureNode(get_node_type())
1233 {
1234  light_manager = NULL;
1235  slot = -1;
1236 }
1237 
1239 {
1240  IESLightNode *node = graph->create_node<IESLightNode>(*this);
1241 
1242  node->light_manager = NULL;
1243  node->slot = -1;
1244 
1245  return node;
1246 }
1247 
1249 {
1250  if (light_manager) {
1251  light_manager->remove_ies(slot);
1252  }
1253 }
1254 
1255 void IESLightNode::get_slot()
1256 {
1257  assert(light_manager);
1258 
1259  if (slot == -1) {
1260  if (ies.empty()) {
1261  slot = light_manager->add_ies_from_file(filename.string());
1262  }
1263  else {
1264  slot = light_manager->add_ies(ies.string());
1265  }
1266  }
1267 }
1268 
1269 void IESLightNode::compile(SVMCompiler &compiler)
1270 {
1271  light_manager = compiler.scene->light_manager;
1272  get_slot();
1273 
1274  ShaderInput *strength_in = input("Strength");
1275  ShaderInput *vector_in = input("Vector");
1276  ShaderOutput *fac_out = output("Fac");
1277 
1278  int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1279 
1280  compiler.add_node(NODE_IES,
1281  compiler.encode_uchar4(compiler.stack_assign_if_linked(strength_in),
1282  vector_offset,
1283  compiler.stack_assign(fac_out),
1284  0),
1285  slot,
1286  __float_as_int(strength));
1287 
1288  tex_mapping.compile_end(compiler, vector_in, vector_offset);
1289 }
1290 
1291 void IESLightNode::compile(OSLCompiler &compiler)
1292 {
1293  light_manager = compiler.scene->light_manager;
1294  get_slot();
1295 
1296  tex_mapping.compile(compiler);
1297 
1298  compiler.parameter_texture_ies("filename", slot);
1299  compiler.add(this, "node_ies_light");
1300 }
1301 
1302 /* White Noise Texture */
1303 
1305 {
1306  NodeType *type = NodeType::add("white_noise_texture", create, NodeType::SHADER);
1307 
1308  static NodeEnum dimensions_enum;
1309  dimensions_enum.insert("1D", 1);
1310  dimensions_enum.insert("2D", 2);
1311  dimensions_enum.insert("3D", 3);
1312  dimensions_enum.insert("4D", 4);
1313  SOCKET_ENUM(dimensions, "Dimensions", dimensions_enum, 3);
1314 
1315  SOCKET_IN_POINT(vector, "Vector", zero_float3());
1316  SOCKET_IN_FLOAT(w, "W", 0.0f);
1317 
1318  SOCKET_OUT_FLOAT(value, "Value");
1319  SOCKET_OUT_COLOR(color, "Color");
1320 
1321  return type;
1322 }
1323 
1324 WhiteNoiseTextureNode::WhiteNoiseTextureNode() : ShaderNode(get_node_type())
1325 {
1326 }
1327 
1329 {
1330  ShaderInput *vector_in = input("Vector");
1331  ShaderInput *w_in = input("W");
1332  ShaderOutput *value_out = output("Value");
1333  ShaderOutput *color_out = output("Color");
1334 
1335  int vector_stack_offset = compiler.stack_assign(vector_in);
1336  int w_stack_offset = compiler.stack_assign(w_in);
1337  int value_stack_offset = compiler.stack_assign(value_out);
1338  int color_stack_offset = compiler.stack_assign(color_out);
1339 
1340  compiler.add_node(NODE_TEX_WHITE_NOISE,
1341  dimensions,
1342  compiler.encode_uchar4(vector_stack_offset, w_stack_offset),
1343  compiler.encode_uchar4(value_stack_offset, color_stack_offset));
1344 }
1345 
1347 {
1348  compiler.parameter(this, "dimensions");
1349  compiler.add(this, "node_white_noise_texture");
1350 }
1351 
1352 /* Musgrave Texture */
1353 
1355 {
1356  NodeType *type = NodeType::add("musgrave_texture", create, NodeType::SHADER);
1357 
1359 
1360  static NodeEnum dimensions_enum;
1361  dimensions_enum.insert("1D", 1);
1362  dimensions_enum.insert("2D", 2);
1363  dimensions_enum.insert("3D", 3);
1364  dimensions_enum.insert("4D", 4);
1365  SOCKET_ENUM(dimensions, "Dimensions", dimensions_enum, 3);
1366 
1367  static NodeEnum type_enum;
1368  type_enum.insert("multifractal", NODE_MUSGRAVE_MULTIFRACTAL);
1369  type_enum.insert("fBM", NODE_MUSGRAVE_FBM);
1370  type_enum.insert("hybrid_multifractal", NODE_MUSGRAVE_HYBRID_MULTIFRACTAL);
1371  type_enum.insert("ridged_multifractal", NODE_MUSGRAVE_RIDGED_MULTIFRACTAL);
1372  type_enum.insert("hetero_terrain", NODE_MUSGRAVE_HETERO_TERRAIN);
1373  SOCKET_ENUM(musgrave_type, "Type", type_enum, NODE_MUSGRAVE_FBM);
1374 
1376  SOCKET_IN_FLOAT(w, "W", 0.0f);
1377  SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
1378  SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
1379  SOCKET_IN_FLOAT(dimension, "Dimension", 2.0f);
1380  SOCKET_IN_FLOAT(lacunarity, "Lacunarity", 2.0f);
1381  SOCKET_IN_FLOAT(offset, "Offset", 0.0f);
1382  SOCKET_IN_FLOAT(gain, "Gain", 1.0f);
1383 
1384  SOCKET_OUT_FLOAT(fac, "Fac");
1385 
1386  return type;
1387 }
1388 
1389 MusgraveTextureNode::MusgraveTextureNode() : TextureNode(get_node_type())
1390 {
1391 }
1392 
1394 {
1395  ShaderInput *vector_in = input("Vector");
1396  ShaderInput *w_in = input("W");
1397  ShaderInput *scale_in = input("Scale");
1398  ShaderInput *detail_in = input("Detail");
1399  ShaderInput *dimension_in = input("Dimension");
1400  ShaderInput *lacunarity_in = input("Lacunarity");
1401  ShaderInput *offset_in = input("Offset");
1402  ShaderInput *gain_in = input("Gain");
1403  ShaderOutput *fac_out = output("Fac");
1404 
1405  int vector_stack_offset = tex_mapping.compile_begin(compiler, vector_in);
1406  int w_stack_offset = compiler.stack_assign_if_linked(w_in);
1407  int scale_stack_offset = compiler.stack_assign_if_linked(scale_in);
1408  int detail_stack_offset = compiler.stack_assign_if_linked(detail_in);
1409  int dimension_stack_offset = compiler.stack_assign_if_linked(dimension_in);
1410  int lacunarity_stack_offset = compiler.stack_assign_if_linked(lacunarity_in);
1411  int offset_stack_offset = compiler.stack_assign_if_linked(offset_in);
1412  int gain_stack_offset = compiler.stack_assign_if_linked(gain_in);
1413  int fac_stack_offset = compiler.stack_assign(fac_out);
1414 
1415  compiler.add_node(
1417  compiler.encode_uchar4(musgrave_type, dimensions, vector_stack_offset, w_stack_offset),
1418  compiler.encode_uchar4(scale_stack_offset,
1419  detail_stack_offset,
1420  dimension_stack_offset,
1421  lacunarity_stack_offset),
1422  compiler.encode_uchar4(offset_stack_offset, gain_stack_offset, fac_stack_offset));
1423  compiler.add_node(
1424  __float_as_int(w), __float_as_int(scale), __float_as_int(detail), __float_as_int(dimension));
1425  compiler.add_node(__float_as_int(lacunarity), __float_as_int(offset), __float_as_int(gain));
1426 
1427  tex_mapping.compile_end(compiler, vector_in, vector_stack_offset);
1428 }
1429 
1431 {
1432  tex_mapping.compile(compiler);
1433 
1434  compiler.parameter(this, "musgrave_type");
1435  compiler.parameter(this, "dimensions");
1436  compiler.add(this, "node_musgrave_texture");
1437 }
1438 
1439 /* Wave Texture */
1440 
1442 {
1443  NodeType *type = NodeType::add("wave_texture", create, NodeType::SHADER);
1444 
1446 
1447  static NodeEnum type_enum;
1448  type_enum.insert("bands", NODE_WAVE_BANDS);
1449  type_enum.insert("rings", NODE_WAVE_RINGS);
1450  SOCKET_ENUM(wave_type, "Type", type_enum, NODE_WAVE_BANDS);
1451 
1452  static NodeEnum bands_direction_enum;
1453  bands_direction_enum.insert("x", NODE_WAVE_BANDS_DIRECTION_X);
1454  bands_direction_enum.insert("y", NODE_WAVE_BANDS_DIRECTION_Y);
1455  bands_direction_enum.insert("z", NODE_WAVE_BANDS_DIRECTION_Z);
1456  bands_direction_enum.insert("diagonal", NODE_WAVE_BANDS_DIRECTION_DIAGONAL);
1457  SOCKET_ENUM(
1458  bands_direction, "Bands Direction", bands_direction_enum, NODE_WAVE_BANDS_DIRECTION_X);
1459 
1460  static NodeEnum rings_direction_enum;
1461  rings_direction_enum.insert("x", NODE_WAVE_RINGS_DIRECTION_X);
1462  rings_direction_enum.insert("y", NODE_WAVE_RINGS_DIRECTION_Y);
1463  rings_direction_enum.insert("z", NODE_WAVE_RINGS_DIRECTION_Z);
1464  rings_direction_enum.insert("spherical", NODE_WAVE_RINGS_DIRECTION_SPHERICAL);
1465  SOCKET_ENUM(
1466  rings_direction, "Rings Direction", rings_direction_enum, NODE_WAVE_BANDS_DIRECTION_X);
1467 
1468  static NodeEnum profile_enum;
1469  profile_enum.insert("sine", NODE_WAVE_PROFILE_SIN);
1470  profile_enum.insert("saw", NODE_WAVE_PROFILE_SAW);
1471  profile_enum.insert("tri", NODE_WAVE_PROFILE_TRI);
1472  SOCKET_ENUM(profile, "Profile", profile_enum, NODE_WAVE_PROFILE_SIN);
1473 
1475  SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
1476  SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f);
1477  SOCKET_IN_FLOAT(detail, "Detail", 2.0f);
1478  SOCKET_IN_FLOAT(detail_scale, "Detail Scale", 0.0f);
1479  SOCKET_IN_FLOAT(detail_roughness, "Detail Roughness", 0.5f);
1480  SOCKET_IN_FLOAT(phase, "Phase Offset", 0.0f);
1481  SOCKET_OUT_COLOR(color, "Color");
1482  SOCKET_OUT_FLOAT(fac, "Fac");
1483 
1484  return type;
1485 }
1486 
1487 WaveTextureNode::WaveTextureNode() : TextureNode(get_node_type())
1488 {
1489 }
1490 
1491 void WaveTextureNode::compile(SVMCompiler &compiler)
1492 {
1493  ShaderInput *vector_in = input("Vector");
1494  ShaderInput *scale_in = input("Scale");
1495  ShaderInput *distortion_in = input("Distortion");
1496  ShaderInput *detail_in = input("Detail");
1497  ShaderInput *dscale_in = input("Detail Scale");
1498  ShaderInput *droughness_in = input("Detail Roughness");
1499  ShaderInput *phase_in = input("Phase Offset");
1500  ShaderOutput *color_out = output("Color");
1501  ShaderOutput *fac_out = output("Fac");
1502 
1503  int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1504 
1505  compiler.add_node(NODE_TEX_WAVE,
1506  compiler.encode_uchar4(wave_type, bands_direction, rings_direction, profile),
1507  compiler.encode_uchar4(vector_offset,
1508  compiler.stack_assign_if_linked(scale_in),
1509  compiler.stack_assign_if_linked(distortion_in)),
1510  compiler.encode_uchar4(compiler.stack_assign_if_linked(detail_in),
1511  compiler.stack_assign_if_linked(dscale_in),
1512  compiler.stack_assign_if_linked(droughness_in),
1513  compiler.stack_assign_if_linked(phase_in)));
1514 
1515  compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(color_out),
1516  compiler.stack_assign_if_linked(fac_out)),
1517  __float_as_int(scale),
1518  __float_as_int(distortion),
1519  __float_as_int(detail));
1520 
1521  compiler.add_node(__float_as_int(detail_scale),
1522  __float_as_int(detail_roughness),
1523  __float_as_int(phase),
1525 
1526  tex_mapping.compile_end(compiler, vector_in, vector_offset);
1527 }
1528 
1529 void WaveTextureNode::compile(OSLCompiler &compiler)
1530 {
1531  tex_mapping.compile(compiler);
1532 
1533  compiler.parameter(this, "wave_type");
1534  compiler.parameter(this, "bands_direction");
1535  compiler.parameter(this, "rings_direction");
1536  compiler.parameter(this, "profile");
1537 
1538  compiler.add(this, "node_wave_texture");
1539 }
1540 
1541 /* Magic Texture */
1542 
1544 {
1545  NodeType *type = NodeType::add("magic_texture", create, NodeType::SHADER);
1546 
1548 
1549  SOCKET_INT(depth, "Depth", 2);
1550 
1552  SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
1553  SOCKET_IN_FLOAT(distortion, "Distortion", 1.0f);
1554 
1555  SOCKET_OUT_COLOR(color, "Color");
1556  SOCKET_OUT_FLOAT(fac, "Fac");
1557 
1558  return type;
1559 }
1560 
1561 MagicTextureNode::MagicTextureNode() : TextureNode(get_node_type())
1562 {
1563 }
1564 
1565 void MagicTextureNode::compile(SVMCompiler &compiler)
1566 {
1567  ShaderInput *vector_in = input("Vector");
1568  ShaderInput *scale_in = input("Scale");
1569  ShaderInput *distortion_in = input("Distortion");
1570  ShaderOutput *color_out = output("Color");
1571  ShaderOutput *fac_out = output("Fac");
1572 
1573  int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1574 
1575  compiler.add_node(NODE_TEX_MAGIC,
1576  compiler.encode_uchar4(depth,
1577  compiler.stack_assign_if_linked(color_out),
1578  compiler.stack_assign_if_linked(fac_out)),
1579  compiler.encode_uchar4(vector_offset,
1580  compiler.stack_assign_if_linked(scale_in),
1581  compiler.stack_assign_if_linked(distortion_in)));
1582  compiler.add_node(__float_as_int(scale), __float_as_int(distortion));
1583 
1584  tex_mapping.compile_end(compiler, vector_in, vector_offset);
1585 }
1586 
1587 void MagicTextureNode::compile(OSLCompiler &compiler)
1588 {
1589  tex_mapping.compile(compiler);
1590 
1591  compiler.parameter(this, "depth");
1592  compiler.add(this, "node_magic_texture");
1593 }
1594 
1595 /* Checker Texture */
1596 
1598 {
1599  NodeType *type = NodeType::add("checker_texture", create, NodeType::SHADER);
1600 
1602 
1604  SOCKET_IN_COLOR(color1, "Color1", zero_float3());
1605  SOCKET_IN_COLOR(color2, "Color2", zero_float3());
1606  SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
1607 
1608  SOCKET_OUT_COLOR(color, "Color");
1609  SOCKET_OUT_FLOAT(fac, "Fac");
1610 
1611  return type;
1612 }
1613 
1614 CheckerTextureNode::CheckerTextureNode() : TextureNode(get_node_type())
1615 {
1616 }
1617 
1619 {
1620  ShaderInput *vector_in = input("Vector");
1621  ShaderInput *color1_in = input("Color1");
1622  ShaderInput *color2_in = input("Color2");
1623  ShaderInput *scale_in = input("Scale");
1624 
1625  ShaderOutput *color_out = output("Color");
1626  ShaderOutput *fac_out = output("Fac");
1627 
1628  int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1629 
1630  compiler.add_node(NODE_TEX_CHECKER,
1631  compiler.encode_uchar4(vector_offset,
1632  compiler.stack_assign(color1_in),
1633  compiler.stack_assign(color2_in),
1634  compiler.stack_assign_if_linked(scale_in)),
1635  compiler.encode_uchar4(compiler.stack_assign_if_linked(color_out),
1636  compiler.stack_assign_if_linked(fac_out)),
1637  __float_as_int(scale));
1638 
1639  tex_mapping.compile_end(compiler, vector_in, vector_offset);
1640 }
1641 
1643 {
1644  tex_mapping.compile(compiler);
1645 
1646  compiler.add(this, "node_checker_texture");
1647 }
1648 
1649 /* Brick Texture */
1650 
1652 {
1653  NodeType *type = NodeType::add("brick_texture", create, NodeType::SHADER);
1654 
1656 
1657  SOCKET_FLOAT(offset, "Offset", 0.5f);
1658  SOCKET_INT(offset_frequency, "Offset Frequency", 2);
1659  SOCKET_FLOAT(squash, "Squash", 1.0f);
1660  SOCKET_INT(squash_frequency, "Squash Frequency", 2);
1661 
1663 
1664  SOCKET_IN_COLOR(color1, "Color1", zero_float3());
1665  SOCKET_IN_COLOR(color2, "Color2", zero_float3());
1666  SOCKET_IN_COLOR(mortar, "Mortar", zero_float3());
1667  SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
1668  SOCKET_IN_FLOAT(mortar_size, "Mortar Size", 0.02f);
1669  SOCKET_IN_FLOAT(mortar_smooth, "Mortar Smooth", 0.0f);
1670  SOCKET_IN_FLOAT(bias, "Bias", 0.0f);
1671  SOCKET_IN_FLOAT(brick_width, "Brick Width", 0.5f);
1672  SOCKET_IN_FLOAT(row_height, "Row Height", 0.25f);
1673 
1674  SOCKET_OUT_COLOR(color, "Color");
1675  SOCKET_OUT_FLOAT(fac, "Fac");
1676 
1677  return type;
1678 }
1679 
1680 BrickTextureNode::BrickTextureNode() : TextureNode(get_node_type())
1681 {
1682 }
1683 
1684 void BrickTextureNode::compile(SVMCompiler &compiler)
1685 {
1686  ShaderInput *vector_in = input("Vector");
1687  ShaderInput *color1_in = input("Color1");
1688  ShaderInput *color2_in = input("Color2");
1689  ShaderInput *mortar_in = input("Mortar");
1690  ShaderInput *scale_in = input("Scale");
1691  ShaderInput *mortar_size_in = input("Mortar Size");
1692  ShaderInput *mortar_smooth_in = input("Mortar Smooth");
1693  ShaderInput *bias_in = input("Bias");
1694  ShaderInput *brick_width_in = input("Brick Width");
1695  ShaderInput *row_height_in = input("Row Height");
1696 
1697  ShaderOutput *color_out = output("Color");
1698  ShaderOutput *fac_out = output("Fac");
1699 
1700  int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1701 
1702  compiler.add_node(NODE_TEX_BRICK,
1703  compiler.encode_uchar4(vector_offset,
1704  compiler.stack_assign(color1_in),
1705  compiler.stack_assign(color2_in),
1706  compiler.stack_assign(mortar_in)),
1707  compiler.encode_uchar4(compiler.stack_assign_if_linked(scale_in),
1708  compiler.stack_assign_if_linked(mortar_size_in),
1709  compiler.stack_assign_if_linked(bias_in),
1710  compiler.stack_assign_if_linked(brick_width_in)),
1711  compiler.encode_uchar4(compiler.stack_assign_if_linked(row_height_in),
1712  compiler.stack_assign_if_linked(color_out),
1713  compiler.stack_assign_if_linked(fac_out),
1714  compiler.stack_assign_if_linked(mortar_smooth_in)));
1715 
1716  compiler.add_node(compiler.encode_uchar4(offset_frequency, squash_frequency),
1717  __float_as_int(scale),
1718  __float_as_int(mortar_size),
1719  __float_as_int(bias));
1720 
1721  compiler.add_node(__float_as_int(brick_width),
1722  __float_as_int(row_height),
1723  __float_as_int(offset),
1724  __float_as_int(squash));
1725 
1726  compiler.add_node(
1728 
1729  tex_mapping.compile_end(compiler, vector_in, vector_offset);
1730 }
1731 
1732 void BrickTextureNode::compile(OSLCompiler &compiler)
1733 {
1734  tex_mapping.compile(compiler);
1735 
1736  compiler.parameter(this, "offset");
1737  compiler.parameter(this, "offset_frequency");
1738  compiler.parameter(this, "squash");
1739  compiler.parameter(this, "squash_frequency");
1740  compiler.add(this, "node_brick_texture");
1741 }
1742 
1743 /* Point Density Texture */
1744 
1746 {
1747  NodeType *type = NodeType::add("point_density_texture", create, NodeType::SHADER);
1748 
1749  SOCKET_STRING(filename, "Filename", ustring());
1750 
1751  static NodeEnum space_enum;
1752  space_enum.insert("object", NODE_TEX_VOXEL_SPACE_OBJECT);
1753  space_enum.insert("world", NODE_TEX_VOXEL_SPACE_WORLD);
1754  SOCKET_ENUM(space, "Space", space_enum, NODE_TEX_VOXEL_SPACE_OBJECT);
1755 
1756  static NodeEnum interpolation_enum;
1757  interpolation_enum.insert("closest", INTERPOLATION_CLOSEST);
1758  interpolation_enum.insert("linear", INTERPOLATION_LINEAR);
1759  interpolation_enum.insert("cubic", INTERPOLATION_CUBIC);
1760  interpolation_enum.insert("smart", INTERPOLATION_SMART);
1761  SOCKET_ENUM(interpolation, "Interpolation", interpolation_enum, INTERPOLATION_LINEAR);
1762 
1763  SOCKET_TRANSFORM(tfm, "Transform", transform_identity());
1764 
1766 
1767  SOCKET_OUT_FLOAT(density, "Density");
1768  SOCKET_OUT_COLOR(color, "Color");
1769 
1770  return type;
1771 }
1772 
1773 PointDensityTextureNode::PointDensityTextureNode() : ShaderNode(get_node_type())
1774 {
1775 }
1776 
1778 {
1779 }
1780 
1782 {
1783  /* Increase image user count for new node. We need to ensure to not call
1784  * add_image again, to work around access of freed data on the Blender
1785  * side. A better solution should be found to avoid this. */
1787  node->handle = handle; /* TODO: not needed? */
1788  return node;
1789 }
1790 
1792 {
1793  if (shader->has_volume)
1795 
1797 }
1798 
1800 {
1802  params.interpolation = interpolation;
1803  return params;
1804 }
1805 
1807 {
1808  ShaderInput *vector_in = input("Vector");
1809  ShaderOutput *density_out = output("Density");
1810  ShaderOutput *color_out = output("Color");
1811 
1812  const bool use_density = !density_out->links.empty();
1813  const bool use_color = !color_out->links.empty();
1814 
1815  if (use_density || use_color) {
1816  if (handle.empty()) {
1817  ImageManager *image_manager = compiler.scene->image_manager;
1818  handle = image_manager->add_image(filename.string(), image_params());
1819  }
1820 
1821  const int slot = handle.svm_slot();
1822  if (slot != -1) {
1823  compiler.stack_assign(vector_in);
1824  compiler.add_node(NODE_TEX_VOXEL,
1825  slot,
1826  compiler.encode_uchar4(compiler.stack_assign(vector_in),
1827  compiler.stack_assign_if_linked(density_out),
1828  compiler.stack_assign_if_linked(color_out),
1829  space));
1830  if (space == NODE_TEX_VOXEL_SPACE_WORLD) {
1831  compiler.add_node(tfm.x);
1832  compiler.add_node(tfm.y);
1833  compiler.add_node(tfm.z);
1834  }
1835  }
1836  else {
1837  if (use_density) {
1838  compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(density_out));
1839  }
1840  if (use_color) {
1841  compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
1842  compiler.add_node(
1843  NODE_VALUE_V,
1845  }
1846  }
1847  }
1848 }
1849 
1851 {
1852  ShaderOutput *density_out = output("Density");
1853  ShaderOutput *color_out = output("Color");
1854 
1855  const bool use_density = !density_out->links.empty();
1856  const bool use_color = !color_out->links.empty();
1857 
1858  if (use_density || use_color) {
1859  if (handle.empty()) {
1860  ImageManager *image_manager = compiler.scene->image_manager;
1861  handle = image_manager->add_image(filename.string(), image_params());
1862  }
1863 
1864  compiler.parameter_texture("filename", handle.svm_slot());
1865  if (space == NODE_TEX_VOXEL_SPACE_WORLD) {
1866  compiler.parameter("mapping", tfm);
1867  compiler.parameter("use_mapping", 1);
1868  }
1869  compiler.parameter(this, "interpolation");
1870  compiler.add(this, "node_voxel_texture");
1871  }
1872 }
1873 
1874 /* Normal */
1875 
1877 {
1878  NodeType *type = NodeType::add("normal", create, NodeType::SHADER);
1879 
1880  SOCKET_VECTOR(direction, "direction", zero_float3());
1881 
1882  SOCKET_IN_NORMAL(normal, "Normal", zero_float3());
1883 
1884  SOCKET_OUT_NORMAL(normal, "Normal");
1885  SOCKET_OUT_FLOAT(dot, "Dot");
1886 
1887  return type;
1888 }
1889 
1890 NormalNode::NormalNode() : ShaderNode(get_node_type())
1891 {
1892 }
1893 
1894 void NormalNode::compile(SVMCompiler &compiler)
1895 {
1896  ShaderInput *normal_in = input("Normal");
1897  ShaderOutput *normal_out = output("Normal");
1898  ShaderOutput *dot_out = output("Dot");
1899 
1900  compiler.add_node(NODE_NORMAL,
1901  compiler.stack_assign(normal_in),
1902  compiler.stack_assign(normal_out),
1903  compiler.stack_assign(dot_out));
1904  compiler.add_node(
1905  __float_as_int(direction.x), __float_as_int(direction.y), __float_as_int(direction.z));
1906 }
1907 
1908 void NormalNode::compile(OSLCompiler &compiler)
1909 {
1910  compiler.parameter(this, "direction");
1911  compiler.add(this, "node_normal");
1912 }
1913 
1914 /* Mapping */
1915 
1917 {
1918  NodeType *type = NodeType::add("mapping", create, NodeType::SHADER);
1919 
1920  static NodeEnum type_enum;
1921  type_enum.insert("point", NODE_MAPPING_TYPE_POINT);
1922  type_enum.insert("texture", NODE_MAPPING_TYPE_TEXTURE);
1923  type_enum.insert("vector", NODE_MAPPING_TYPE_VECTOR);
1924  type_enum.insert("normal", NODE_MAPPING_TYPE_NORMAL);
1925  SOCKET_ENUM(mapping_type, "Type", type_enum, NODE_MAPPING_TYPE_POINT);
1926 
1927  SOCKET_IN_POINT(vector, "Vector", zero_float3());
1928  SOCKET_IN_POINT(location, "Location", zero_float3());
1929  SOCKET_IN_POINT(rotation, "Rotation", zero_float3());
1930  SOCKET_IN_POINT(scale, "Scale", one_float3());
1931 
1932  SOCKET_OUT_POINT(vector, "Vector");
1933 
1934  return type;
1935 }
1936 
1937 MappingNode::MappingNode() : ShaderNode(get_node_type())
1938 {
1939 }
1940 
1942 {
1943  if (folder.all_inputs_constant()) {
1944  float3 result = svm_mapping((NodeMappingType)mapping_type, vector, location, rotation, scale);
1945  folder.make_constant(result);
1946  }
1947  else {
1948  folder.fold_mapping((NodeMappingType)mapping_type);
1949  }
1950 }
1951 
1952 void MappingNode::compile(SVMCompiler &compiler)
1953 {
1954  ShaderInput *vector_in = input("Vector");
1955  ShaderInput *location_in = input("Location");
1956  ShaderInput *rotation_in = input("Rotation");
1957  ShaderInput *scale_in = input("Scale");
1958  ShaderOutput *vector_out = output("Vector");
1959 
1960  int vector_stack_offset = compiler.stack_assign(vector_in);
1961  int location_stack_offset = compiler.stack_assign(location_in);
1962  int rotation_stack_offset = compiler.stack_assign(rotation_in);
1963  int scale_stack_offset = compiler.stack_assign(scale_in);
1964  int result_stack_offset = compiler.stack_assign(vector_out);
1965 
1966  compiler.add_node(
1967  NODE_MAPPING,
1968  mapping_type,
1969  compiler.encode_uchar4(
1970  vector_stack_offset, location_stack_offset, rotation_stack_offset, scale_stack_offset),
1971  result_stack_offset);
1972 }
1973 
1974 void MappingNode::compile(OSLCompiler &compiler)
1975 {
1976  compiler.parameter(this, "mapping_type");
1977  compiler.add(this, "node_mapping");
1978 }
1979 
1980 /* RGBToBW */
1981 
1983 {
1984  NodeType *type = NodeType::add("rgb_to_bw", create, NodeType::SHADER);
1985 
1986  SOCKET_IN_COLOR(color, "Color", zero_float3());
1987  SOCKET_OUT_FLOAT(val, "Val");
1988 
1989  return type;
1990 }
1991 
1992 RGBToBWNode::RGBToBWNode() : ShaderNode(get_node_type())
1993 {
1994 }
1995 
1997 {
1998  if (folder.all_inputs_constant()) {
1999  float val = folder.scene->shader_manager->linear_rgb_to_gray(color);
2000  folder.make_constant(val);
2001  }
2002 }
2003 
2004 void RGBToBWNode::compile(SVMCompiler &compiler)
2005 {
2006  compiler.add_node(NODE_CONVERT,
2008  compiler.stack_assign(inputs[0]),
2009  compiler.stack_assign(outputs[0]));
2010 }
2011 
2012 void RGBToBWNode::compile(OSLCompiler &compiler)
2013 {
2014  compiler.add(this, "node_rgb_to_bw");
2015 }
2016 
2017 /* Convert */
2018 
2019 const NodeType *ConvertNode::node_types[ConvertNode::MAX_TYPE][ConvertNode::MAX_TYPE];
2020 bool ConvertNode::initialized = ConvertNode::register_types();
2021 
2022 Node *ConvertNode::create(const NodeType *type)
2023 {
2024  return new ConvertNode(type->inputs[0].type, type->outputs[0].type);
2025 }
2026 
2027 bool ConvertNode::register_types()
2028 {
2029  const int num_types = 8;
2038 
2039  for (size_t i = 0; i < num_types; i++) {
2040  SocketType::Type from = types[i];
2041  ustring from_name(SocketType::type_name(from));
2042  ustring from_value_name("value_" + from_name.string());
2043 
2044  for (size_t j = 0; j < num_types; j++) {
2045  SocketType::Type to = types[j];
2046  ustring to_name(SocketType::type_name(to));
2047  ustring to_value_name("value_" + to_name.string());
2048 
2049  string node_name = "convert_" + from_name.string() + "_to_" + to_name.string();
2050  NodeType *type = NodeType::add(node_name.c_str(), create, NodeType::SHADER);
2051 
2052  type->register_input(from_value_name,
2053  from_value_name,
2054  from,
2057  NULL,
2058  NULL,
2060  type->register_output(to_value_name, to_value_name, to);
2061 
2062  assert(from < MAX_TYPE);
2063  assert(to < MAX_TYPE);
2064 
2065  node_types[from][to] = type;
2066  }
2067  }
2068 
2069  return true;
2070 }
2071 
2073  : ShaderNode(node_types[from_][to_])
2074 {
2075  from = from_;
2076  to = to_;
2077 
2078  if (from == to)
2080  else if (autoconvert)
2082 }
2083 
2084 /* Union usage requires a manual copy constructor. */
2086  : ShaderNode(other),
2087  from(other.from),
2088  to(other.to),
2089  value_color(other.value_color),
2090  value_string(other.value_string)
2091 {
2092 }
2093 
2095 {
2096  /* proxy nodes should have been removed at this point */
2098 
2099  /* TODO(DingTo): conversion from/to int is not supported yet, don't fold in that case */
2100 
2101  if (folder.all_inputs_constant()) {
2102  if (from == SocketType::FLOAT) {
2103  if (SocketType::is_float3(to)) {
2105  }
2106  }
2107  else if (SocketType::is_float3(from)) {
2108  if (to == SocketType::FLOAT) {
2109  if (from == SocketType::COLOR) {
2110  /* color to float */
2111  float val = folder.scene->shader_manager->linear_rgb_to_gray(value_color);
2112  folder.make_constant(val);
2113  }
2114  else {
2115  /* vector/point/normal to float */
2117  }
2118  }
2119  else if (SocketType::is_float3(to)) {
2120  folder.make_constant(value_color);
2121  }
2122  }
2123  }
2124  else {
2125  ShaderInput *in = inputs[0];
2126  ShaderNode *prev = in->link->parent;
2127 
2128  /* no-op conversion of A to B to A */
2129  if (prev->type == node_types[to][from]) {
2130  ShaderInput *prev_in = prev->inputs[0];
2131 
2133  prev_in->link) {
2134  folder.bypass(prev_in->link);
2135  }
2136  }
2137  }
2138 }
2139 
2140 void ConvertNode::compile(SVMCompiler &compiler)
2141 {
2142  /* proxy nodes should have been removed at this point */
2144 
2145  ShaderInput *in = inputs[0];
2146  ShaderOutput *out = outputs[0];
2147 
2148  if (from == SocketType::FLOAT) {
2149  if (to == SocketType::INT)
2150  /* float to int */
2151  compiler.add_node(
2152  NODE_CONVERT, NODE_CONVERT_FI, compiler.stack_assign(in), compiler.stack_assign(out));
2153  else
2154  /* float to float3 */
2155  compiler.add_node(
2156  NODE_CONVERT, NODE_CONVERT_FV, compiler.stack_assign(in), compiler.stack_assign(out));
2157  }
2158  else if (from == SocketType::INT) {
2159  if (to == SocketType::FLOAT)
2160  /* int to float */
2161  compiler.add_node(
2162  NODE_CONVERT, NODE_CONVERT_IF, compiler.stack_assign(in), compiler.stack_assign(out));
2163  else
2164  /* int to vector/point/normal */
2165  compiler.add_node(
2166  NODE_CONVERT, NODE_CONVERT_IV, compiler.stack_assign(in), compiler.stack_assign(out));
2167  }
2168  else if (to == SocketType::FLOAT) {
2169  if (from == SocketType::COLOR)
2170  /* color to float */
2171  compiler.add_node(
2172  NODE_CONVERT, NODE_CONVERT_CF, compiler.stack_assign(in), compiler.stack_assign(out));
2173  else
2174  /* vector/point/normal to float */
2175  compiler.add_node(
2176  NODE_CONVERT, NODE_CONVERT_VF, compiler.stack_assign(in), compiler.stack_assign(out));
2177  }
2178  else if (to == SocketType::INT) {
2179  if (from == SocketType::COLOR)
2180  /* color to int */
2181  compiler.add_node(
2182  NODE_CONVERT, NODE_CONVERT_CI, compiler.stack_assign(in), compiler.stack_assign(out));
2183  else
2184  /* vector/point/normal to int */
2185  compiler.add_node(
2186  NODE_CONVERT, NODE_CONVERT_VI, compiler.stack_assign(in), compiler.stack_assign(out));
2187  }
2188  else {
2189  /* float3 to float3 */
2190  if (in->link) {
2191  /* no op in SVM */
2192  compiler.stack_link(in, out);
2193  }
2194  else {
2195  /* set 0,0,0 value */
2196  compiler.add_node(NODE_VALUE_V, compiler.stack_assign(out));
2197  compiler.add_node(NODE_VALUE_V, value_color);
2198  }
2199  }
2200 }
2201 
2202 void ConvertNode::compile(OSLCompiler &compiler)
2203 {
2204  /* proxy nodes should have been removed at this point */
2206 
2207  if (from == SocketType::FLOAT)
2208  compiler.add(this, "node_convert_from_float");
2209  else if (from == SocketType::INT)
2210  compiler.add(this, "node_convert_from_int");
2211  else if (from == SocketType::COLOR)
2212  compiler.add(this, "node_convert_from_color");
2213  else if (from == SocketType::VECTOR)
2214  compiler.add(this, "node_convert_from_vector");
2215  else if (from == SocketType::POINT)
2216  compiler.add(this, "node_convert_from_point");
2217  else if (from == SocketType::NORMAL)
2218  compiler.add(this, "node_convert_from_normal");
2219  else
2220  assert(0);
2221 }
2222 
2223 /* Base type for all closure-type nodes */
2224 
2225 BsdfBaseNode::BsdfBaseNode(const NodeType *node_type) : ShaderNode(node_type)
2226 {
2228 }
2229 
2231 {
2232  /* detect if anything is plugged into the normal input besides the default */
2233  ShaderInput *normal_in = input("Normal");
2234  return (normal_in && normal_in->link &&
2236 }
2237 
2238 /* BSDF Closure */
2239 
2240 BsdfNode::BsdfNode(const NodeType *node_type) : BsdfBaseNode(node_type)
2241 {
2242 }
2243 
2245  ShaderInput *param1,
2246  ShaderInput *param2,
2247  ShaderInput *param3,
2248  ShaderInput *param4)
2249 {
2250  ShaderInput *color_in = input("Color");
2251  ShaderInput *normal_in = input("Normal");
2252  ShaderInput *tangent_in = input("Tangent");
2253 
2254  if (color_in->link)
2255  compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
2256  else
2257  compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
2258 
2259  int normal_offset = (normal_in) ? compiler.stack_assign_if_linked(normal_in) : SVM_STACK_INVALID;
2260  int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) :
2262  int param3_offset = (param3) ? compiler.stack_assign(param3) : SVM_STACK_INVALID;
2263  int param4_offset = (param4) ? compiler.stack_assign(param4) : SVM_STACK_INVALID;
2264 
2265  compiler.add_node(
2267  compiler.encode_uchar4(closure,
2268  (param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID,
2269  (param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID,
2270  compiler.closure_mix_weight_offset()),
2271  __float_as_int((param1) ? get_float(param1->socket_type) : 0.0f),
2272  __float_as_int((param2) ? get_float(param2->socket_type) : 0.0f));
2273 
2274  compiler.add_node(normal_offset, tangent_offset, param3_offset, param4_offset);
2275 }
2276 
2277 void BsdfNode::compile(SVMCompiler &compiler)
2278 {
2279  compile(compiler, NULL, NULL);
2280 }
2281 
2282 void BsdfNode::compile(OSLCompiler & /*compiler*/)
2283 {
2284  assert(0);
2285 }
2286 
2287 /* Anisotropic BSDF Closure */
2288 
2290 {
2291  NodeType *type = NodeType::add("anisotropic_bsdf", create, NodeType::SHADER);
2292 
2293  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2295  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2296 
2297  static NodeEnum distribution_enum;
2298  distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
2299  distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID);
2300  distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
2301  distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
2302  SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID);
2303 
2304  SOCKET_IN_VECTOR(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT);
2305 
2306  SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
2307  SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.5f);
2308  SOCKET_IN_FLOAT(rotation, "Rotation", 0.0f);
2309 
2310  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2311 
2312  return type;
2313 }
2314 
2315 AnisotropicBsdfNode::AnisotropicBsdfNode() : BsdfNode(get_node_type())
2316 {
2318 }
2319 
2321 {
2322  if (shader->has_surface) {
2323  ShaderInput *tangent_in = input("Tangent");
2324 
2325  if (!tangent_in->link)
2327  }
2328 
2330 }
2331 
2333 {
2334  closure = distribution;
2335 
2338  compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color"));
2339  else
2340  BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"));
2341 }
2342 
2344 {
2345  compiler.parameter(this, "distribution");
2346  compiler.add(this, "node_anisotropic_bsdf");
2347 }
2348 
2349 /* Glossy BSDF Closure */
2350 
2352 {
2353  NodeType *type = NodeType::add("glossy_bsdf", create, NodeType::SHADER);
2354 
2355  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2357  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2358 
2359  static NodeEnum distribution_enum;
2360  distribution_enum.insert("sharp", CLOSURE_BSDF_REFLECTION_ID);
2361  distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
2362  distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID);
2363  distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
2364  distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
2365  SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID);
2366  SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
2367 
2368  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2369 
2370  return type;
2371 }
2372 
2373 GlossyBsdfNode::GlossyBsdfNode() : BsdfNode(get_node_type())
2374 {
2376  distribution_orig = NBUILTIN_CLOSURES;
2377 }
2378 
2380 {
2381  if (distribution_orig == NBUILTIN_CLOSURES) {
2382  roughness_orig = roughness;
2383  distribution_orig = distribution;
2384  }
2385  else {
2386  /* By default we use original values, so we don't worry about restoring
2387  * defaults later one and can only do override when needed.
2388  */
2389  roughness = roughness_orig;
2390  distribution = distribution_orig;
2391  }
2392  Integrator *integrator = scene->integrator;
2393  ShaderInput *roughness_input = input("Roughness");
2394  if (integrator->get_filter_glossy() == 0.0f) {
2395  /* Fallback to Sharp closure for Roughness close to 0.
2396  * Note: Keep the epsilon in sync with kernel!
2397  */
2398  if (!roughness_input->link && roughness <= 1e-4f) {
2399  VLOG(1) << "Using sharp glossy BSDF.";
2400  distribution = CLOSURE_BSDF_REFLECTION_ID;
2401  }
2402  }
2403  else {
2404  /* If filter glossy is used we replace Sharp glossy with GGX so we can
2405  * benefit from closure blur to remove unwanted noise.
2406  */
2407  if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_REFLECTION_ID) {
2408  VLOG(1) << "Using GGX glossy with filter glossy.";
2409  distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
2410  roughness = 0.0f;
2411  }
2412  }
2413  closure = distribution;
2414 }
2415 
2417 {
2418  ShaderInput *roughness_input = input("Roughness");
2419  return !roughness_input->link &&
2420  (distribution == CLOSURE_BSDF_REFLECTION_ID || roughness <= 1e-4f);
2421 }
2422 
2423 void GlossyBsdfNode::compile(SVMCompiler &compiler)
2424 {
2425  closure = distribution;
2426 
2428  BsdfNode::compile(compiler, NULL, NULL);
2430  BsdfNode::compile(compiler, input("Roughness"), NULL, NULL, input("Color"));
2431  else
2432  BsdfNode::compile(compiler, input("Roughness"), NULL);
2433 }
2434 
2435 void GlossyBsdfNode::compile(OSLCompiler &compiler)
2436 {
2437  compiler.parameter(this, "distribution");
2438  compiler.add(this, "node_glossy_bsdf");
2439 }
2440 
2441 /* Glass BSDF Closure */
2442 
2444 {
2445  NodeType *type = NodeType::add("glass_bsdf", create, NodeType::SHADER);
2446 
2447  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2449  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2450 
2451  static NodeEnum distribution_enum;
2452  distribution_enum.insert("sharp", CLOSURE_BSDF_SHARP_GLASS_ID);
2453  distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID);
2454  distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
2455  distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
2456  SOCKET_ENUM(
2457  distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
2458  SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
2459  SOCKET_IN_FLOAT(IOR, "IOR", 0.3f);
2460 
2461  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2462 
2463  return type;
2464 }
2465 
2466 GlassBsdfNode::GlassBsdfNode() : BsdfNode(get_node_type())
2467 {
2468  closure = CLOSURE_BSDF_SHARP_GLASS_ID;
2469  distribution_orig = NBUILTIN_CLOSURES;
2470 }
2471 
2473 {
2474  if (distribution_orig == NBUILTIN_CLOSURES) {
2475  roughness_orig = roughness;
2476  distribution_orig = distribution;
2477  }
2478  else {
2479  /* By default we use original values, so we don't worry about restoring
2480  * defaults later one and can only do override when needed.
2481  */
2482  roughness = roughness_orig;
2483  distribution = distribution_orig;
2484  }
2485  Integrator *integrator = scene->integrator;
2486  ShaderInput *roughness_input = input("Roughness");
2487  if (integrator->get_filter_glossy() == 0.0f) {
2488  /* Fallback to Sharp closure for Roughness close to 0.
2489  * Note: Keep the epsilon in sync with kernel!
2490  */
2491  if (!roughness_input->link && roughness <= 1e-4f) {
2492  VLOG(1) << "Using sharp glass BSDF.";
2493  distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
2494  }
2495  }
2496  else {
2497  /* If filter glossy is used we replace Sharp glossy with GGX so we can
2498  * benefit from closure blur to remove unwanted noise.
2499  */
2500  if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_SHARP_GLASS_ID) {
2501  VLOG(1) << "Using GGX glass with filter glossy.";
2502  distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
2503  roughness = 0.0f;
2504  }
2505  }
2506  closure = distribution;
2507 }
2508 
2510 {
2511  ShaderInput *roughness_input = input("Roughness");
2512  return !roughness_input->link &&
2513  (distribution == CLOSURE_BSDF_SHARP_GLASS_ID || roughness <= 1e-4f);
2514 }
2515 
2516 void GlassBsdfNode::compile(SVMCompiler &compiler)
2517 {
2518  closure = distribution;
2519 
2521  BsdfNode::compile(compiler, NULL, input("IOR"));
2523  BsdfNode::compile(compiler, input("Roughness"), input("IOR"), input("Color"));
2524  else
2525  BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
2526 }
2527 
2528 void GlassBsdfNode::compile(OSLCompiler &compiler)
2529 {
2530  compiler.parameter(this, "distribution");
2531  compiler.add(this, "node_glass_bsdf");
2532 }
2533 
2534 /* Refraction BSDF Closure */
2535 
2537 {
2538  NodeType *type = NodeType::add("refraction_bsdf", create, NodeType::SHADER);
2539 
2540  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2542  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2543 
2544  static NodeEnum distribution_enum;
2545  distribution_enum.insert("sharp", CLOSURE_BSDF_REFRACTION_ID);
2546  distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
2547  distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
2548  SOCKET_ENUM(
2549  distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
2550 
2551  SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
2552  SOCKET_IN_FLOAT(IOR, "IOR", 0.3f);
2553 
2554  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2555 
2556  return type;
2557 }
2558 
2559 RefractionBsdfNode::RefractionBsdfNode() : BsdfNode(get_node_type())
2560 {
2561  closure = CLOSURE_BSDF_REFRACTION_ID;
2562  distribution_orig = NBUILTIN_CLOSURES;
2563 }
2564 
2566 {
2567  if (distribution_orig == NBUILTIN_CLOSURES) {
2568  roughness_orig = roughness;
2569  distribution_orig = distribution;
2570  }
2571  else {
2572  /* By default we use original values, so we don't worry about restoring
2573  * defaults later one and can only do override when needed.
2574  */
2575  roughness = roughness_orig;
2576  distribution = distribution_orig;
2577  }
2578  Integrator *integrator = scene->integrator;
2579  ShaderInput *roughness_input = input("Roughness");
2580  if (integrator->get_filter_glossy() == 0.0f) {
2581  /* Fallback to Sharp closure for Roughness close to 0.
2582  * Note: Keep the epsilon in sync with kernel!
2583  */
2584  if (!roughness_input->link && roughness <= 1e-4f) {
2585  VLOG(1) << "Using sharp refraction BSDF.";
2586  distribution = CLOSURE_BSDF_REFRACTION_ID;
2587  }
2588  }
2589  else {
2590  /* If filter glossy is used we replace Sharp glossy with GGX so we can
2591  * benefit from closure blur to remove unwanted noise.
2592  */
2593  if (roughness_input->link == NULL && distribution == CLOSURE_BSDF_REFRACTION_ID) {
2594  VLOG(1) << "Using GGX refraction with filter glossy.";
2596  roughness = 0.0f;
2597  }
2598  }
2599  closure = distribution;
2600 }
2601 
2603 {
2604  ShaderInput *roughness_input = input("Roughness");
2605  return !roughness_input->link &&
2606  (distribution == CLOSURE_BSDF_REFRACTION_ID || roughness <= 1e-4f);
2607 }
2608 
2610 {
2611  closure = distribution;
2612 
2614  BsdfNode::compile(compiler, NULL, input("IOR"));
2615  else
2616  BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
2617 }
2618 
2620 {
2621  compiler.parameter(this, "distribution");
2622  compiler.add(this, "node_refraction_bsdf");
2623 }
2624 
2625 /* Toon BSDF Closure */
2626 
2628 {
2629  NodeType *type = NodeType::add("toon_bsdf", create, NodeType::SHADER);
2630 
2631  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2633  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2634 
2635  static NodeEnum component_enum;
2636  component_enum.insert("diffuse", CLOSURE_BSDF_DIFFUSE_TOON_ID);
2637  component_enum.insert("glossy", CLOSURE_BSDF_GLOSSY_TOON_ID);
2638  SOCKET_ENUM(component, "Component", component_enum, CLOSURE_BSDF_DIFFUSE_TOON_ID);
2639  SOCKET_IN_FLOAT(size, "Size", 0.5f);
2640  SOCKET_IN_FLOAT(smooth, "Smooth", 0.0f);
2641 
2642  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2643 
2644  return type;
2645 }
2646 
2647 ToonBsdfNode::ToonBsdfNode() : BsdfNode(get_node_type())
2648 {
2649  closure = CLOSURE_BSDF_DIFFUSE_TOON_ID;
2650 }
2651 
2652 void ToonBsdfNode::compile(SVMCompiler &compiler)
2653 {
2654  closure = component;
2655 
2656  BsdfNode::compile(compiler, input("Size"), input("Smooth"));
2657 }
2658 
2659 void ToonBsdfNode::compile(OSLCompiler &compiler)
2660 {
2661  compiler.parameter(this, "component");
2662  compiler.add(this, "node_toon_bsdf");
2663 }
2664 
2665 /* Velvet BSDF Closure */
2666 
2668 {
2669  NodeType *type = NodeType::add("velvet_bsdf", create, NodeType::SHADER);
2670 
2671  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2673  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2674  SOCKET_IN_FLOAT(sigma, "Sigma", 1.0f);
2675 
2676  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2677 
2678  return type;
2679 }
2680 
2681 VelvetBsdfNode::VelvetBsdfNode() : BsdfNode(get_node_type())
2682 {
2684 }
2685 
2686 void VelvetBsdfNode::compile(SVMCompiler &compiler)
2687 {
2688  BsdfNode::compile(compiler, input("Sigma"), NULL);
2689 }
2690 
2691 void VelvetBsdfNode::compile(OSLCompiler &compiler)
2692 {
2693  compiler.add(this, "node_velvet_bsdf");
2694 }
2695 
2696 /* Diffuse BSDF Closure */
2697 
2699 {
2700  NodeType *type = NodeType::add("diffuse_bsdf", create, NodeType::SHADER);
2701 
2702  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2704  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2705  SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f);
2706 
2707  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2708 
2709  return type;
2710 }
2711 
2712 DiffuseBsdfNode::DiffuseBsdfNode() : BsdfNode(get_node_type())
2713 {
2714  closure = CLOSURE_BSDF_DIFFUSE_ID;
2715 }
2716 
2717 void DiffuseBsdfNode::compile(SVMCompiler &compiler)
2718 {
2719  BsdfNode::compile(compiler, input("Roughness"), NULL);
2720 }
2721 
2722 void DiffuseBsdfNode::compile(OSLCompiler &compiler)
2723 {
2724  compiler.add(this, "node_diffuse_bsdf");
2725 }
2726 
2727 /* Disney principled BSDF Closure */
2729 {
2730  NodeType *type = NodeType::add("principled_bsdf", create, NodeType::SHADER);
2731 
2732  static NodeEnum distribution_enum;
2733  distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
2734  distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
2735  SOCKET_ENUM(
2736  distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
2737 
2738  static NodeEnum subsurface_method_enum;
2739  subsurface_method_enum.insert("burley", CLOSURE_BSSRDF_PRINCIPLED_ID);
2740  subsurface_method_enum.insert("random_walk", CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID);
2741  SOCKET_ENUM(subsurface_method,
2742  "Subsurface Method",
2743  subsurface_method_enum,
2745 
2746  SOCKET_IN_COLOR(base_color, "Base Color", make_float3(0.8f, 0.8f, 0.8f));
2747  SOCKET_IN_COLOR(subsurface_color, "Subsurface Color", make_float3(0.8f, 0.8f, 0.8f));
2748  SOCKET_IN_FLOAT(metallic, "Metallic", 0.0f);
2749  SOCKET_IN_FLOAT(subsurface, "Subsurface", 0.0f);
2750  SOCKET_IN_VECTOR(subsurface_radius, "Subsurface Radius", make_float3(0.1f, 0.1f, 0.1f));
2751  SOCKET_IN_FLOAT(specular, "Specular", 0.0f);
2752  SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
2753  SOCKET_IN_FLOAT(specular_tint, "Specular Tint", 0.0f);
2754  SOCKET_IN_FLOAT(anisotropic, "Anisotropic", 0.0f);
2755  SOCKET_IN_FLOAT(sheen, "Sheen", 0.0f);
2756  SOCKET_IN_FLOAT(sheen_tint, "Sheen Tint", 0.0f);
2757  SOCKET_IN_FLOAT(clearcoat, "Clearcoat", 0.0f);
2758  SOCKET_IN_FLOAT(clearcoat_roughness, "Clearcoat Roughness", 0.03f);
2759  SOCKET_IN_FLOAT(ior, "IOR", 0.0f);
2760  SOCKET_IN_FLOAT(transmission, "Transmission", 0.0f);
2761  SOCKET_IN_FLOAT(transmission_roughness, "Transmission Roughness", 0.0f);
2762  SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
2763  SOCKET_IN_COLOR(emission, "Emission", zero_float3());
2764  SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 1.0f);
2765  SOCKET_IN_FLOAT(alpha, "Alpha", 1.0f);
2767  SOCKET_IN_NORMAL(clearcoat_normal, "Clearcoat Normal", zero_float3(), SocketType::LINK_NORMAL);
2768  SOCKET_IN_NORMAL(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT);
2769  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2770 
2771  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2772 
2773  return type;
2774 }
2775 
2776 PrincipledBsdfNode::PrincipledBsdfNode() : BsdfBaseNode(get_node_type())
2777 {
2778  closure = CLOSURE_BSDF_PRINCIPLED_ID;
2780  distribution_orig = NBUILTIN_CLOSURES;
2781 }
2782 
2784 {
2785  ShaderOutput *principled_out = output("BSDF");
2786 
2787  ShaderInput *emission_in = input("Emission");
2788  ShaderInput *emission_strength_in = input("Emission Strength");
2789  if ((emission_in->link || emission != zero_float3()) &&
2790  (emission_strength_in->link || emission_strength != 0.0f)) {
2791  /* Create add closure and emission, and relink inputs. */
2792  AddClosureNode *add = graph->create_node<AddClosureNode>();
2793  EmissionNode *emission_node = graph->create_node<EmissionNode>();
2794  ShaderOutput *new_out = add->output("Closure");
2795 
2796  graph->add(add);
2797  graph->add(emission_node);
2798 
2799  graph->relink(emission_strength_in, emission_node->input("Strength"));
2800  graph->relink(emission_in, emission_node->input("Color"));
2801  graph->relink(principled_out, new_out);
2802  graph->connect(emission_node->output("Emission"), add->input("Closure1"));
2803  graph->connect(principled_out, add->input("Closure2"));
2804 
2805  principled_out = new_out;
2806  }
2807  else {
2808  /* Disconnect unused links if the other value is zero, required before
2809  * we remove the input from the node entirely. */
2810  if (emission_in->link) {
2811  emission_in->disconnect();
2812  }
2813  if (emission_strength_in->link) {
2814  emission_strength_in->disconnect();
2815  }
2816  }
2817 
2818  ShaderInput *alpha_in = input("Alpha");
2819  if (alpha_in->link || alpha != 1.0f) {
2820  /* Create mix and transparent BSDF for alpha transparency. */
2821  MixClosureNode *mix = graph->create_node<MixClosureNode>();
2822  TransparentBsdfNode *transparent = graph->create_node<TransparentBsdfNode>();
2823 
2824  graph->add(mix);
2825  graph->add(transparent);
2826 
2827  graph->relink(alpha_in, mix->input("Fac"));
2828  graph->relink(principled_out, mix->output("Closure"));
2829  graph->connect(transparent->output("BSDF"), mix->input("Closure1"));
2830  graph->connect(principled_out, mix->input("Closure2"));
2831  }
2832 
2833  remove_input(emission_in);
2834  remove_input(emission_strength_in);
2835  remove_input(alpha_in);
2836 }
2837 
2839 {
2840  ShaderInput *subsurface_in = input("Subsurface");
2841  return (subsurface_in->link != NULL || subsurface > CLOSURE_WEIGHT_CUTOFF);
2842 }
2843 
2845 {
2846  if (shader->has_surface) {
2847  ShaderInput *tangent_in = input("Tangent");
2848 
2849  if (!tangent_in->link)
2851  }
2852 
2854 }
2855 
2857  ShaderInput *p_metallic,
2858  ShaderInput *p_subsurface,
2859  ShaderInput *p_subsurface_radius,
2860  ShaderInput *p_specular,
2861  ShaderInput *p_roughness,
2862  ShaderInput *p_specular_tint,
2863  ShaderInput *p_anisotropic,
2864  ShaderInput *p_sheen,
2865  ShaderInput *p_sheen_tint,
2866  ShaderInput *p_clearcoat,
2867  ShaderInput *p_clearcoat_roughness,
2868  ShaderInput *p_ior,
2869  ShaderInput *p_transmission,
2870  ShaderInput *p_anisotropic_rotation,
2871  ShaderInput *p_transmission_roughness)
2872 {
2873  ShaderInput *base_color_in = input("Base Color");
2874  ShaderInput *subsurface_color_in = input("Subsurface Color");
2875  ShaderInput *normal_in = input("Normal");
2876  ShaderInput *clearcoat_normal_in = input("Clearcoat Normal");
2877  ShaderInput *tangent_in = input("Tangent");
2878 
2879  float3 weight = one_float3();
2880 
2881  compiler.add_node(NODE_CLOSURE_SET_WEIGHT, weight);
2882 
2883  int normal_offset = compiler.stack_assign_if_linked(normal_in);
2884  int clearcoat_normal_offset = compiler.stack_assign_if_linked(clearcoat_normal_in);
2885  int tangent_offset = compiler.stack_assign_if_linked(tangent_in);
2886  int specular_offset = compiler.stack_assign(p_specular);
2887  int roughness_offset = compiler.stack_assign(p_roughness);
2888  int specular_tint_offset = compiler.stack_assign(p_specular_tint);
2889  int anisotropic_offset = compiler.stack_assign(p_anisotropic);
2890  int sheen_offset = compiler.stack_assign(p_sheen);
2891  int sheen_tint_offset = compiler.stack_assign(p_sheen_tint);
2892  int clearcoat_offset = compiler.stack_assign(p_clearcoat);
2893  int clearcoat_roughness_offset = compiler.stack_assign(p_clearcoat_roughness);
2894  int ior_offset = compiler.stack_assign(p_ior);
2895  int transmission_offset = compiler.stack_assign(p_transmission);
2896  int transmission_roughness_offset = compiler.stack_assign(p_transmission_roughness);
2897  int anisotropic_rotation_offset = compiler.stack_assign(p_anisotropic_rotation);
2898  int subsurface_radius_offset = compiler.stack_assign(p_subsurface_radius);
2899 
2900  compiler.add_node(NODE_CLOSURE_BSDF,
2901  compiler.encode_uchar4(closure,
2902  compiler.stack_assign(p_metallic),
2903  compiler.stack_assign(p_subsurface),
2904  compiler.closure_mix_weight_offset()),
2905  __float_as_int((p_metallic) ? get_float(p_metallic->socket_type) : 0.0f),
2906  __float_as_int((p_subsurface) ? get_float(p_subsurface->socket_type) : 0.0f));
2907 
2908  compiler.add_node(
2909  normal_offset,
2910  tangent_offset,
2911  compiler.encode_uchar4(
2912  specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset),
2913  compiler.encode_uchar4(
2914  sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset));
2915 
2916  compiler.add_node(compiler.encode_uchar4(ior_offset,
2917  transmission_offset,
2918  anisotropic_rotation_offset,
2919  transmission_roughness_offset),
2920  distribution,
2921  subsurface_method,
2923 
2924  float3 bc_default = get_float3(base_color_in->socket_type);
2925 
2926  compiler.add_node(
2927  ((base_color_in->link) ? compiler.stack_assign(base_color_in) : SVM_STACK_INVALID),
2928  __float_as_int(bc_default.x),
2929  __float_as_int(bc_default.y),
2930  __float_as_int(bc_default.z));
2931 
2932  compiler.add_node(
2933  clearcoat_normal_offset, subsurface_radius_offset, SVM_STACK_INVALID, SVM_STACK_INVALID);
2934 
2935  float3 ss_default = get_float3(subsurface_color_in->socket_type);
2936 
2937  compiler.add_node(((subsurface_color_in->link) ? compiler.stack_assign(subsurface_color_in) :
2939  __float_as_int(ss_default.x),
2940  __float_as_int(ss_default.y),
2941  __float_as_int(ss_default.z));
2942 }
2943 
2945 {
2946  ShaderInput *roughness_input = input("Roughness");
2947  return !roughness_input->link && roughness <= 1e-4f;
2948 }
2949 
2951 {
2952  compile(compiler,
2953  input("Metallic"),
2954  input("Subsurface"),
2955  input("Subsurface Radius"),
2956  input("Specular"),
2957  input("Roughness"),
2958  input("Specular Tint"),
2959  input("Anisotropic"),
2960  input("Sheen"),
2961  input("Sheen Tint"),
2962  input("Clearcoat"),
2963  input("Clearcoat Roughness"),
2964  input("IOR"),
2965  input("Transmission"),
2966  input("Anisotropic Rotation"),
2967  input("Transmission Roughness"));
2968 }
2969 
2971 {
2972  compiler.parameter(this, "distribution");
2973  compiler.parameter(this, "subsurface_method");
2974  compiler.add(this, "node_principled_bsdf");
2975 }
2976 
2978 {
2979  return has_surface_bssrdf() && has_bump();
2980 }
2981 
2982 /* Translucent BSDF Closure */
2983 
2985 {
2986  NodeType *type = NodeType::add("translucent_bsdf", create, NodeType::SHADER);
2987 
2988  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
2990  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
2991 
2992  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
2993 
2994  return type;
2995 }
2996 
2997 TranslucentBsdfNode::TranslucentBsdfNode() : BsdfNode(get_node_type())
2998 {
2999  closure = CLOSURE_BSDF_TRANSLUCENT_ID;
3000 }
3001 
3003 {
3004  BsdfNode::compile(compiler, NULL, NULL);
3005 }
3006 
3008 {
3009  compiler.add(this, "node_translucent_bsdf");
3010 }
3011 
3012 /* Transparent BSDF Closure */
3013 
3015 {
3016  NodeType *type = NodeType::add("transparent_bsdf", create, NodeType::SHADER);
3017 
3018  SOCKET_IN_COLOR(color, "Color", one_float3());
3019  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3020 
3021  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
3022 
3023  return type;
3024 }
3025 
3026 TransparentBsdfNode::TransparentBsdfNode() : BsdfNode(get_node_type())
3027 {
3028  closure = CLOSURE_BSDF_TRANSPARENT_ID;
3029 }
3030 
3032 {
3033  BsdfNode::compile(compiler, NULL, NULL);
3034 }
3035 
3037 {
3038  compiler.add(this, "node_transparent_bsdf");
3039 }
3040 
3041 /* Subsurface Scattering Closure */
3042 
3044 {
3045  NodeType *type = NodeType::add("subsurface_scattering", create, NodeType::SHADER);
3046 
3047  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3049  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3050 
3051  static NodeEnum falloff_enum;
3052  falloff_enum.insert("cubic", CLOSURE_BSSRDF_CUBIC_ID);
3053  falloff_enum.insert("gaussian", CLOSURE_BSSRDF_GAUSSIAN_ID);
3054  falloff_enum.insert("burley", CLOSURE_BSSRDF_BURLEY_ID);
3055  falloff_enum.insert("random_walk", CLOSURE_BSSRDF_RANDOM_WALK_ID);
3056  SOCKET_ENUM(falloff, "Falloff", falloff_enum, CLOSURE_BSSRDF_BURLEY_ID);
3057  SOCKET_IN_FLOAT(scale, "Scale", 0.01f);
3058  SOCKET_IN_VECTOR(radius, "Radius", make_float3(0.1f, 0.1f, 0.1f));
3059  SOCKET_IN_FLOAT(sharpness, "Sharpness", 0.0f);
3060  SOCKET_IN_FLOAT(texture_blur, "Texture Blur", 1.0f);
3061 
3062  SOCKET_OUT_CLOSURE(BSSRDF, "BSSRDF");
3063 
3064  return type;
3065 }
3066 
3067 SubsurfaceScatteringNode::SubsurfaceScatteringNode() : BsdfNode(get_node_type())
3068 {
3069  closure = falloff;
3070 }
3071 
3073 {
3074  closure = falloff;
3076  compiler, input("Scale"), input("Texture Blur"), input("Radius"), input("Sharpness"));
3077 }
3078 
3080 {
3081  closure = falloff;
3082  compiler.parameter(this, "falloff");
3083  compiler.add(this, "node_subsurface_scattering");
3084 }
3085 
3087 {
3088  /* detect if anything is plugged into the normal input besides the default */
3089  ShaderInput *normal_in = input("Normal");
3090  return (normal_in->link &&
3092 }
3093 
3094 /* Emissive Closure */
3095 
3097 {
3098  NodeType *type = NodeType::add("emission", create, NodeType::SHADER);
3099 
3100  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3101  SOCKET_IN_FLOAT(strength, "Strength", 10.0f);
3102  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3103 
3104  SOCKET_OUT_CLOSURE(emission, "Emission");
3105 
3106  return type;
3107 }
3108 
3109 EmissionNode::EmissionNode() : ShaderNode(get_node_type())
3110 {
3111 }
3112 
3113 void EmissionNode::compile(SVMCompiler &compiler)
3114 {
3115  ShaderInput *color_in = input("Color");
3116  ShaderInput *strength_in = input("Strength");
3117 
3118  if (color_in->link || strength_in->link) {
3119  compiler.add_node(
3120  NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
3121  }
3122  else
3123  compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
3124 
3126 }
3127 
3128 void EmissionNode::compile(OSLCompiler &compiler)
3129 {
3130  compiler.add(this, "node_emission");
3131 }
3132 
3134 {
3135  ShaderInput *color_in = input("Color");
3136  ShaderInput *strength_in = input("Strength");
3137 
3138  if ((!color_in->link && color == zero_float3()) || (!strength_in->link && strength == 0.0f)) {
3139  folder.discard();
3140  }
3141 }
3142 
3143 /* Background Closure */
3144 
3146 {
3147  NodeType *type = NodeType::add("background_shader", create, NodeType::SHADER);
3148 
3149  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3150  SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
3151  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3152 
3153  SOCKET_OUT_CLOSURE(background, "Background");
3154 
3155  return type;
3156 }
3157 
3158 BackgroundNode::BackgroundNode() : ShaderNode(get_node_type())
3159 {
3160 }
3161 
3162 void BackgroundNode::compile(SVMCompiler &compiler)
3163 {
3164  ShaderInput *color_in = input("Color");
3165  ShaderInput *strength_in = input("Strength");
3166 
3167  if (color_in->link || strength_in->link) {
3168  compiler.add_node(
3169  NODE_EMISSION_WEIGHT, compiler.stack_assign(color_in), compiler.stack_assign(strength_in));
3170  }
3171  else
3172  compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color * strength);
3173 
3175 }
3176 
3177 void BackgroundNode::compile(OSLCompiler &compiler)
3178 {
3179  compiler.add(this, "node_background");
3180 }
3181 
3183 {
3184  ShaderInput *color_in = input("Color");
3185  ShaderInput *strength_in = input("Strength");
3186 
3187  if ((!color_in->link && color == zero_float3()) || (!strength_in->link && strength == 0.0f)) {
3188  folder.discard();
3189  }
3190 }
3191 
3192 /* Holdout Closure */
3193 
3195 {
3196  NodeType *type = NodeType::add("holdout", create, NodeType::SHADER);
3197 
3198  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3199  SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3200 
3201  SOCKET_OUT_CLOSURE(holdout, "Holdout");
3202 
3203  return type;
3204 }
3205 
3206 HoldoutNode::HoldoutNode() : ShaderNode(get_node_type())
3207 {
3208 }
3209 
3210 void HoldoutNode::compile(SVMCompiler &compiler)
3211 {
3212  float3 value = one_float3();
3213 
3214  compiler.add_node(NODE_CLOSURE_SET_WEIGHT, value);
3216 }
3217 
3218 void HoldoutNode::compile(OSLCompiler &compiler)
3219 {
3220  compiler.add(this, "node_holdout");
3221 }
3222 
3223 /* Ambient Occlusion */
3224 
3226 {
3227  NodeType *type = NodeType::add("ambient_occlusion", create, NodeType::SHADER);
3228 
3229  SOCKET_INT(samples, "Samples", 16);
3230 
3231  SOCKET_IN_COLOR(color, "Color", one_float3());
3232  SOCKET_IN_FLOAT(distance, "Distance", 1.0f);
3234 
3235  SOCKET_BOOLEAN(inside, "Inside", false);
3236  SOCKET_BOOLEAN(only_local, "Only Local", false);
3237 
3238  SOCKET_OUT_COLOR(color, "Color");
3239  SOCKET_OUT_FLOAT(ao, "AO");
3240 
3241  return type;
3242 }
3243 
3244 AmbientOcclusionNode::AmbientOcclusionNode() : ShaderNode(get_node_type())
3245 {
3246 }
3247 
3249 {
3250  ShaderInput *color_in = input("Color");
3251  ShaderInput *distance_in = input("Distance");
3252  ShaderInput *normal_in = input("Normal");
3253  ShaderOutput *color_out = output("Color");
3254  ShaderOutput *ao_out = output("AO");
3255 
3256  int flags = (inside ? NODE_AO_INSIDE : 0) | (only_local ? NODE_AO_ONLY_LOCAL : 0);
3257 
3258  if (!distance_in->link && distance == 0.0f) {
3259  flags |= NODE_AO_GLOBAL_RADIUS;
3260  }
3261 
3263  compiler.encode_uchar4(flags,
3264  compiler.stack_assign_if_linked(distance_in),
3265  compiler.stack_assign_if_linked(normal_in),
3266  compiler.stack_assign(ao_out)),
3267  compiler.encode_uchar4(compiler.stack_assign(color_in),
3268  compiler.stack_assign(color_out),
3269  samples),
3271 }
3272 
3274 {
3275  compiler.parameter(this, "samples");
3276  compiler.parameter(this, "inside");
3277  compiler.parameter(this, "only_local");
3278  compiler.add(this, "node_ambient_occlusion");
3279 }
3280 
3281 /* Volume Closure */
3282 
3283 VolumeNode::VolumeNode(const NodeType *node_type) : ShaderNode(node_type)
3284 {
3286 }
3287 
3288 void VolumeNode::compile(SVMCompiler &compiler, ShaderInput *param1, ShaderInput *param2)
3289 {
3290  ShaderInput *color_in = input("Color");
3291 
3292  if (color_in->link)
3293  compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
3294  else
3295  compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
3296 
3297  compiler.add_node(
3299  compiler.encode_uchar4(closure,
3300  (param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID,
3301  (param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID,
3302  compiler.closure_mix_weight_offset()),
3303  __float_as_int((param1) ? get_float(param1->socket_type) : 0.0f),
3304  __float_as_int((param2) ? get_float(param2->socket_type) : 0.0f));
3305 }
3306 
3307 void VolumeNode::compile(SVMCompiler &compiler)
3308 {
3309  compile(compiler, NULL, NULL);
3310 }
3311 
3312 void VolumeNode::compile(OSLCompiler & /*compiler*/)
3313 {
3314  assert(0);
3315 }
3316 
3317 /* Absorption Volume Closure */
3318 
3320 {
3321  NodeType *type = NodeType::add("absorption_volume", create, NodeType::SHADER);
3322 
3323  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3324  SOCKET_IN_FLOAT(density, "Density", 1.0f);
3325  SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3326 
3327  SOCKET_OUT_CLOSURE(volume, "Volume");
3328 
3329  return type;
3330 }
3331 
3332 AbsorptionVolumeNode::AbsorptionVolumeNode() : VolumeNode(get_node_type())
3333 {
3334  closure = CLOSURE_VOLUME_ABSORPTION_ID;
3335 }
3336 
3338 {
3339  VolumeNode::compile(compiler, input("Density"), NULL);
3340 }
3341 
3343 {
3344  compiler.add(this, "node_absorption_volume");
3345 }
3346 
3347 /* Scatter Volume Closure */
3348 
3350 {
3351  NodeType *type = NodeType::add("scatter_volume", create, NodeType::SHADER);
3352 
3353  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3354  SOCKET_IN_FLOAT(density, "Density", 1.0f);
3355  SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
3356  SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3357 
3358  SOCKET_OUT_CLOSURE(volume, "Volume");
3359 
3360  return type;
3361 }
3362 
3363 ScatterVolumeNode::ScatterVolumeNode() : VolumeNode(get_node_type())
3364 {
3366 }
3367 
3369 {
3370  VolumeNode::compile(compiler, input("Density"), input("Anisotropy"));
3371 }
3372 
3374 {
3375  compiler.add(this, "node_scatter_volume");
3376 }
3377 
3378 /* Principled Volume Closure */
3379 
3381 {
3382  NodeType *type = NodeType::add("principled_volume", create, NodeType::SHADER);
3383 
3384  SOCKET_IN_STRING(density_attribute, "Density Attribute", ustring());
3385  SOCKET_IN_STRING(color_attribute, "Color Attribute", ustring());
3386  SOCKET_IN_STRING(temperature_attribute, "Temperature Attribute", ustring());
3387 
3388  SOCKET_IN_COLOR(color, "Color", make_float3(0.5f, 0.5f, 0.5f));
3389  SOCKET_IN_FLOAT(density, "Density", 1.0f);
3390  SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
3391  SOCKET_IN_COLOR(absorption_color, "Absorption Color", zero_float3());
3392  SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 0.0f);
3393  SOCKET_IN_COLOR(emission_color, "Emission Color", one_float3());
3394  SOCKET_IN_FLOAT(blackbody_intensity, "Blackbody Intensity", 0.0f);
3395  SOCKET_IN_COLOR(blackbody_tint, "Blackbody Tint", one_float3());
3396  SOCKET_IN_FLOAT(temperature, "Temperature", 1000.0f);
3397  SOCKET_IN_FLOAT(volume_mix_weight, "VolumeMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3398 
3399  SOCKET_OUT_CLOSURE(volume, "Volume");
3400 
3401  return type;
3402 }
3403 
3404 PrincipledVolumeNode::PrincipledVolumeNode() : VolumeNode(get_node_type())
3405 {
3407  density_attribute = ustring("density");
3408  temperature_attribute = ustring("temperature");
3409 }
3410 
3412 {
3413  if (shader->has_volume) {
3414  ShaderInput *density_in = input("Density");
3415  ShaderInput *blackbody_in = input("Blackbody Intensity");
3416 
3417  if (density_in->link || density > 0.0f) {
3418  attributes->add_standard(density_attribute);
3419  attributes->add_standard(color_attribute);
3420  }
3421 
3422  if (blackbody_in->link || blackbody_intensity > 0.0f) {
3423  attributes->add_standard(temperature_attribute);
3424  }
3425 
3427  }
3428 
3430 }
3431 
3433 {
3434  ShaderInput *color_in = input("Color");
3435  ShaderInput *density_in = input("Density");
3436  ShaderInput *anisotropy_in = input("Anisotropy");
3437  ShaderInput *absorption_color_in = input("Absorption Color");
3438  ShaderInput *emission_in = input("Emission Strength");
3439  ShaderInput *emission_color_in = input("Emission Color");
3440  ShaderInput *blackbody_in = input("Blackbody Intensity");
3441  ShaderInput *blackbody_tint_in = input("Blackbody Tint");
3442  ShaderInput *temperature_in = input("Temperature");
3443 
3444  if (color_in->link)
3445  compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
3446  else
3447  compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color);
3448 
3450  compiler.encode_uchar4(compiler.stack_assign_if_linked(density_in),
3451  compiler.stack_assign_if_linked(anisotropy_in),
3452  compiler.stack_assign(absorption_color_in),
3453  compiler.closure_mix_weight_offset()),
3454  compiler.encode_uchar4(compiler.stack_assign_if_linked(emission_in),
3455  compiler.stack_assign(emission_color_in),
3456  compiler.stack_assign_if_linked(blackbody_in),
3457  compiler.stack_assign(temperature_in)),
3458  compiler.stack_assign(blackbody_tint_in));
3459 
3460  int attr_density = compiler.attribute_standard(density_attribute);
3461  int attr_color = compiler.attribute_standard(color_attribute);
3462  int attr_temperature = compiler.attribute_standard(temperature_attribute);
3463 
3464  compiler.add_node(__float_as_int(density),
3465  __float_as_int(anisotropy),
3466  __float_as_int(emission_strength),
3467  __float_as_int(blackbody_intensity));
3468 
3469  compiler.add_node(attr_density, attr_color, attr_temperature);
3470 }
3471 
3473 {
3474  if (Attribute::name_standard(density_attribute.c_str())) {
3475  density_attribute = ustring("geom:" + density_attribute.string());
3476  }
3477  if (Attribute::name_standard(color_attribute.c_str())) {
3478  color_attribute = ustring("geom:" + color_attribute.string());
3479  }
3480  if (Attribute::name_standard(temperature_attribute.c_str())) {
3481  temperature_attribute = ustring("geom:" + temperature_attribute.string());
3482  }
3483 
3484  compiler.add(this, "node_principled_volume");
3485 }
3486 
3487 /* Principled Hair BSDF Closure */
3488 
3490 {
3491  NodeType *type = NodeType::add("principled_hair_bsdf", create, NodeType::SHADER);
3492 
3493  /* Color parametrization specified as enum. */
3494  static NodeEnum parametrization_enum;
3495  parametrization_enum.insert("Direct coloring", NODE_PRINCIPLED_HAIR_REFLECTANCE);
3496  parametrization_enum.insert("Melanin concentration", NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION);
3497  parametrization_enum.insert("Absorption coefficient", NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION);
3498  SOCKET_ENUM(
3499  parametrization, "Parametrization", parametrization_enum, NODE_PRINCIPLED_HAIR_REFLECTANCE);
3500 
3501  /* Initialize sockets to their default values. */
3502  SOCKET_IN_COLOR(color, "Color", make_float3(0.017513f, 0.005763f, 0.002059f));
3503  SOCKET_IN_FLOAT(melanin, "Melanin", 0.8f);
3504  SOCKET_IN_FLOAT(melanin_redness, "Melanin Redness", 1.0f);
3505  SOCKET_IN_COLOR(tint, "Tint", make_float3(1.f, 1.f, 1.f));
3506  SOCKET_IN_VECTOR(absorption_coefficient,
3507  "Absorption Coefficient",
3508  make_float3(0.245531f, 0.52f, 1.365f),
3510 
3511  SOCKET_IN_FLOAT(offset, "Offset", 2.f * M_PI_F / 180.f);
3512  SOCKET_IN_FLOAT(roughness, "Roughness", 0.3f);
3513  SOCKET_IN_FLOAT(radial_roughness, "Radial Roughness", 0.3f);
3514  SOCKET_IN_FLOAT(coat, "Coat", 0.0f);
3515  SOCKET_IN_FLOAT(ior, "IOR", 1.55f);
3516 
3517  SOCKET_IN_FLOAT(random_roughness, "Random Roughness", 0.0f);
3518  SOCKET_IN_FLOAT(random_color, "Random Color", 0.0f);
3519  SOCKET_IN_FLOAT(random, "Random", 0.0f);
3520 
3522  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3523 
3524  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
3525 
3526  return type;
3527 }
3528 
3529 PrincipledHairBsdfNode::PrincipledHairBsdfNode() : BsdfBaseNode(get_node_type())
3530 {
3532 }
3533 
3534 /* Enable retrieving Hair Info -> Random if Random isn't linked. */
3536 {
3537  if (!input("Random")->link) {
3539  }
3541 }
3542 
3543 /* Prepares the input data for the SVM shader. */
3545 {
3547 
3548  ShaderInput *roughness_in = input("Roughness");
3549  ShaderInput *radial_roughness_in = input("Radial Roughness");
3550  ShaderInput *random_roughness_in = input("Random Roughness");
3551  ShaderInput *offset_in = input("Offset");
3552  ShaderInput *coat_in = input("Coat");
3553  ShaderInput *ior_in = input("IOR");
3554  ShaderInput *melanin_in = input("Melanin");
3555  ShaderInput *melanin_redness_in = input("Melanin Redness");
3556  ShaderInput *random_color_in = input("Random Color");
3557 
3558  int color_ofs = compiler.stack_assign(input("Color"));
3559  int tint_ofs = compiler.stack_assign(input("Tint"));
3560  int absorption_coefficient_ofs = compiler.stack_assign(input("Absorption Coefficient"));
3561 
3562  ShaderInput *random_in = input("Random");
3563  int attr_random = random_in->link ? SVM_STACK_INVALID :
3564  compiler.attribute(ATTR_STD_CURVE_RANDOM);
3565 
3566  /* Encode all parameters into data nodes. */
3567  compiler.add_node(NODE_CLOSURE_BSDF,
3568  /* Socket IDs can be packed 4 at a time into a single data packet */
3569  compiler.encode_uchar4(closure,
3570  compiler.stack_assign_if_linked(roughness_in),
3571  compiler.stack_assign_if_linked(radial_roughness_in),
3572  compiler.closure_mix_weight_offset()),
3573  /* The rest are stored as unsigned integers */
3575  __float_as_uint(radial_roughness));
3576 
3577  compiler.add_node(compiler.stack_assign_if_linked(input("Normal")),
3578  compiler.encode_uchar4(compiler.stack_assign_if_linked(offset_in),
3579  compiler.stack_assign_if_linked(ior_in),
3580  color_ofs,
3581  parametrization),
3582  __float_as_uint(offset),
3583  __float_as_uint(ior));
3584 
3585  compiler.add_node(compiler.encode_uchar4(compiler.stack_assign_if_linked(coat_in),
3586  compiler.stack_assign_if_linked(melanin_in),
3587  compiler.stack_assign_if_linked(melanin_redness_in),
3588  absorption_coefficient_ofs),
3589  __float_as_uint(coat),
3590  __float_as_uint(melanin),
3591  __float_as_uint(melanin_redness));
3592 
3593  compiler.add_node(compiler.encode_uchar4(tint_ofs,
3594  compiler.stack_assign_if_linked(random_in),
3595  compiler.stack_assign_if_linked(random_color_in),
3596  compiler.stack_assign_if_linked(random_roughness_in)),
3598  __float_as_uint(random_color),
3599  __float_as_uint(random_roughness));
3600 
3601  compiler.add_node(
3602  compiler.encode_uchar4(
3604  attr_random,
3607 }
3608 
3609 /* Prepares the input data for the OSL shader. */
3611 {
3612  compiler.parameter(this, "parametrization");
3613  compiler.add(this, "node_principled_hair_bsdf");
3614 }
3615 
3616 /* Hair BSDF Closure */
3617 
3619 {
3620  NodeType *type = NodeType::add("hair_bsdf", create, NodeType::SHADER);
3621 
3622  SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
3624  SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
3625 
3626  static NodeEnum component_enum;
3627  component_enum.insert("reflection", CLOSURE_BSDF_HAIR_REFLECTION_ID);
3628  component_enum.insert("transmission", CLOSURE_BSDF_HAIR_TRANSMISSION_ID);
3629  SOCKET_ENUM(component, "Component", component_enum, CLOSURE_BSDF_HAIR_REFLECTION_ID);
3630  SOCKET_IN_FLOAT(offset, "Offset", 0.0f);
3631  SOCKET_IN_FLOAT(roughness_u, "RoughnessU", 0.2f);
3632  SOCKET_IN_FLOAT(roughness_v, "RoughnessV", 0.2f);
3633  SOCKET_IN_VECTOR(tangent, "Tangent", zero_float3());
3634 
3635  SOCKET_OUT_CLOSURE(BSDF, "BSDF");
3636 
3637  return type;
3638 }
3639 
3640 HairBsdfNode::HairBsdfNode() : BsdfNode(get_node_type())
3641 {
3643 }
3644 
3645 void HairBsdfNode::compile(SVMCompiler &compiler)
3646 {
3647  closure = component;
3648 
3649  BsdfNode::compile(compiler, input("RoughnessU"), input("RoughnessV"), input("Offset"));
3650 }
3651 
3652 void HairBsdfNode::compile(OSLCompiler &compiler)
3653 {
3654  compiler.parameter(this, "component");
3655  compiler.add(this, "node_hair_bsdf");
3656 }
3657 
3658 /* Geometry */
3659 
3661 {
3662  NodeType *type = NodeType::add("geometry", create, NodeType::SHADER);
3663 
3665  normal_osl, "NormalIn", zero_float3(), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
3666 
3667  SOCKET_OUT_POINT(position, "Position");
3668  SOCKET_OUT_NORMAL(normal, "Normal");
3669  SOCKET_OUT_NORMAL(tangent, "Tangent");
3670  SOCKET_OUT_NORMAL(true_normal, "True Normal");
3671  SOCKET_OUT_VECTOR(incoming, "Incoming");
3672  SOCKET_OUT_POINT(parametric, "Parametric");
3673  SOCKET_OUT_FLOAT(backfacing, "Backfacing");
3674  SOCKET_OUT_FLOAT(pointiness, "Pointiness");
3675  SOCKET_OUT_FLOAT(random_per_island, "Random Per Island");
3676 
3677  return type;
3678 }
3679 
3680 GeometryNode::GeometryNode() : ShaderNode(get_node_type())
3681 {
3682  special_type = SHADER_SPECIAL_TYPE_GEOMETRY;
3683 }
3684 
3686 {
3687  if (shader->has_surface) {
3688  if (!output("Tangent")->links.empty()) {
3690  }
3691  if (!output("Pointiness")->links.empty()) {
3693  }
3694  if (!output("Random Per Island")->links.empty()) {
3696  }
3697  }
3698 
3700 }
3701 
3702 void GeometryNode::compile(SVMCompiler &compiler)
3703 {
3704  ShaderOutput *out;
3705  ShaderNodeType geom_node = NODE_GEOMETRY;
3706  ShaderNodeType attr_node = NODE_ATTR;
3707 
3708  if (bump == SHADER_BUMP_DX) {
3709  geom_node = NODE_GEOMETRY_BUMP_DX;
3710  attr_node = NODE_ATTR_BUMP_DX;
3711  }
3712  else if (bump == SHADER_BUMP_DY) {
3713  geom_node = NODE_GEOMETRY_BUMP_DY;
3714  attr_node = NODE_ATTR_BUMP_DY;
3715  }
3716 
3717  out = output("Position");
3718  if (!out->links.empty()) {
3719  compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out));
3720  }
3721 
3722  out = output("Normal");
3723  if (!out->links.empty()) {
3724  compiler.add_node(geom_node, NODE_GEOM_N, compiler.stack_assign(out));
3725  }
3726 
3727  out = output("Tangent");
3728  if (!out->links.empty()) {
3729  compiler.add_node(geom_node, NODE_GEOM_T, compiler.stack_assign(out));
3730  }
3731 
3732  out = output("True Normal");
3733  if (!out->links.empty()) {
3734  compiler.add_node(geom_node, NODE_GEOM_Ng, compiler.stack_assign(out));
3735  }
3736 
3737  out = output("Incoming");
3738  if (!out->links.empty()) {
3739  compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out));
3740  }
3741 
3742  out = output("Parametric");
3743  if (!out->links.empty()) {
3744  compiler.add_node(geom_node, NODE_GEOM_uv, compiler.stack_assign(out));
3745  }
3746 
3747  out = output("Backfacing");
3748  if (!out->links.empty()) {
3749  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, compiler.stack_assign(out));
3750  }
3751 
3752  out = output("Pointiness");
3753  if (!out->links.empty()) {
3754  if (compiler.output_type() != SHADER_TYPE_VOLUME) {
3755  compiler.add_node(
3756  attr_node, ATTR_STD_POINTINESS, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
3757  }
3758  else {
3759  compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out));
3760  }
3761  }
3762 
3763  out = output("Random Per Island");
3764  if (!out->links.empty()) {
3765  if (compiler.output_type() != SHADER_TYPE_VOLUME) {
3766  compiler.add_node(attr_node,
3768  compiler.stack_assign(out),
3770  }
3771  else {
3772  compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out));
3773  }
3774  }
3775 }
3776 
3777 void GeometryNode::compile(OSLCompiler &compiler)
3778 {
3779  if (bump == SHADER_BUMP_DX)
3780  compiler.parameter("bump_offset", "dx");
3781  else if (bump == SHADER_BUMP_DY)
3782  compiler.parameter("bump_offset", "dy");
3783  else
3784  compiler.parameter("bump_offset", "center");
3785 
3786  compiler.add(this, "node_geometry");
3787 }
3788 
3790 {
3791  ShaderOutput *out;
3792  int result = ShaderNode::get_group();
3793 
3794  /* Backfacing uses NODE_LIGHT_PATH */
3795  out = output("Backfacing");
3796  if (!out->links.empty()) {
3798  }
3799 
3800  return result;
3801 }
3802 
3803 /* TextureCoordinate */
3804 
3806 {
3807  NodeType *type = NodeType::add("texture_coordinate", create, NodeType::SHADER);
3808 
3809  SOCKET_BOOLEAN(from_dupli, "From Dupli", false);
3810  SOCKET_BOOLEAN(use_transform, "Use Transform", false);
3811  SOCKET_TRANSFORM(ob_tfm, "Object Transform", transform_identity());
3812 
3814  normal_osl, "NormalIn", zero_float3(), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
3815 
3816  SOCKET_OUT_POINT(generated, "Generated");
3817  SOCKET_OUT_NORMAL(normal, "Normal");
3818  SOCKET_OUT_POINT(UV, "UV");
3819  SOCKET_OUT_POINT(object, "Object");
3820  SOCKET_OUT_POINT(camera, "Camera");
3821  SOCKET_OUT_POINT(window, "Window");
3822  SOCKET_OUT_NORMAL(reflection, "Reflection");
3823 
3824  return type;
3825 }
3826 
3827 TextureCoordinateNode::TextureCoordinateNode() : ShaderNode(get_node_type())
3828 {
3829 }
3830 
3832 {
3833  if (shader->has_surface) {
3834  if (!from_dupli) {
3835  if (!output("Generated")->links.empty())
3837  if (!output("UV")->links.empty())
3838  attributes->add(ATTR_STD_UV);
3839  }
3840  }
3841 
3842  if (shader->has_volume) {
3843  if (!from_dupli) {
3844  if (!output("Generated")->links.empty()) {
3846  }
3847  }
3848  }
3849 
3851 }
3852 
3854 {
3855  ShaderOutput *out;
3856  ShaderNodeType texco_node = NODE_TEX_COORD;
3857  ShaderNodeType attr_node = NODE_ATTR;
3858  ShaderNodeType geom_node = NODE_GEOMETRY;
3859 
3860  if (bump == SHADER_BUMP_DX) {
3861  texco_node = NODE_TEX_COORD_BUMP_DX;
3862  attr_node = NODE_ATTR_BUMP_DX;
3863  geom_node = NODE_GEOMETRY_BUMP_DX;
3864  }
3865  else if (bump == SHADER_BUMP_DY) {
3866  texco_node = NODE_TEX_COORD_BUMP_DY;
3867  attr_node = NODE_ATTR_BUMP_DY;
3868  geom_node = NODE_GEOMETRY_BUMP_DY;
3869  }
3870 
3871  out = output("Generated");
3872  if (!out->links.empty()) {
3873  if (compiler.background) {
3874  compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out));
3875  }
3876  else {
3877  if (from_dupli) {
3878  compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, compiler.stack_assign(out));
3879  }
3880  else if (compiler.output_type() == SHADER_TYPE_VOLUME) {
3881  compiler.add_node(texco_node, NODE_TEXCO_VOLUME_GENERATED, compiler.stack_assign(out));
3882  }
3883  else {
3884  int attr = compiler.attribute(ATTR_STD_GENERATED);
3885  compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
3886  }
3887  }
3888  }
3889 
3890  out = output("Normal");
3891  if (!out->links.empty()) {
3892  compiler.add_node(texco_node, NODE_TEXCO_NORMAL, compiler.stack_assign(out));
3893  }
3894 
3895  out = output("UV");
3896  if (!out->links.empty()) {
3897  if (from_dupli) {
3898  compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
3899  }
3900  else {
3901  int attr = compiler.attribute(ATTR_STD_UV);
3902  compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
3903  }
3904  }
3905 
3906  out = output("Object");
3907  if (!out->links.empty()) {
3908  compiler.add_node(texco_node, NODE_TEXCO_OBJECT, compiler.stack_assign(out), use_transform);
3909  if (use_transform) {
3910  Transform ob_itfm = transform_inverse(ob_tfm);
3911  compiler.add_node(ob_itfm.x);
3912  compiler.add_node(ob_itfm.y);
3913  compiler.add_node(ob_itfm.z);
3914  }
3915  }
3916 
3917  out = output("Camera");
3918  if (!out->links.empty()) {
3919  compiler.add_node(texco_node, NODE_TEXCO_CAMERA, compiler.stack_assign(out));
3920  }
3921 
3922  out = output("Window");
3923  if (!out->links.empty()) {
3924  compiler.add_node(texco_node, NODE_TEXCO_WINDOW, compiler.stack_assign(out));
3925  }
3926 
3927  out = output("Reflection");
3928  if (!out->links.empty()) {
3929  if (compiler.background) {
3930  compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out));
3931  }
3932  else {
3933  compiler.add_node(texco_node, NODE_TEXCO_REFLECTION, compiler.stack_assign(out));
3934  }
3935  }
3936 }
3937 
3939 {
3940  if (bump == SHADER_BUMP_DX)
3941  compiler.parameter("bump_offset", "dx");
3942  else if (bump == SHADER_BUMP_DY)
3943  compiler.parameter("bump_offset", "dy");
3944  else
3945  compiler.parameter("bump_offset", "center");
3946 
3947  if (compiler.background)
3948  compiler.parameter("is_background", true);
3949  if (compiler.output_type() == SHADER_TYPE_VOLUME)
3950  compiler.parameter("is_volume", true);
3951  compiler.parameter(this, "use_transform");
3952  Transform ob_itfm = transform_inverse(ob_tfm);
3953  compiler.parameter("object_itfm", ob_itfm);
3954 
3955  compiler.parameter(this, "from_dupli");
3956 
3957  compiler.add(this, "node_texture_coordinate");
3958 }
3959 
3960 /* UV Map */
3961 
3963 {
3964  NodeType *type = NodeType::add("uvmap", create, NodeType::SHADER);
3965 
3966  SOCKET_STRING(attribute, "attribute", ustring());
3967  SOCKET_IN_BOOLEAN(from_dupli, "from dupli", false);
3968 
3969  SOCKET_OUT_POINT(UV, "UV");
3970 
3971  return type;
3972 }
3973 
3974 UVMapNode::UVMapNode() : ShaderNode(get_node_type())
3975 {
3976 }
3977 
3979 {
3980  if (shader->has_surface) {
3981  if (!from_dupli) {
3982  if (!output("UV")->links.empty()) {
3983  if (attribute != "")
3984  attributes->add(attribute);
3985  else
3986  attributes->add(ATTR_STD_UV);
3987  }
3988  }
3989  }
3990 
3992 }
3993 
3994 void UVMapNode::compile(SVMCompiler &compiler)
3995 {
3996  ShaderOutput *out = output("UV");
3997  ShaderNodeType texco_node = NODE_TEX_COORD;
3998  ShaderNodeType attr_node = NODE_ATTR;
3999  int attr;
4000 
4001  if (bump == SHADER_BUMP_DX) {
4002  texco_node = NODE_TEX_COORD_BUMP_DX;
4003  attr_node = NODE_ATTR_BUMP_DX;
4004  }
4005  else if (bump == SHADER_BUMP_DY) {
4006  texco_node = NODE_TEX_COORD_BUMP_DY;
4007  attr_node = NODE_ATTR_BUMP_DY;
4008  }
4009 
4010  if (!out->links.empty()) {
4011  if (from_dupli) {
4012  compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
4013  }
4014  else {
4015  if (attribute != "")
4016  attr = compiler.attribute(attribute);
4017  else
4018  attr = compiler.attribute(ATTR_STD_UV);
4019 
4020  compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3);
4021  }
4022  }
4023 }
4024 
4025 void UVMapNode::compile(OSLCompiler &compiler)
4026 {
4027  if (bump == SHADER_BUMP_DX)
4028  compiler.parameter("bump_offset", "dx");
4029  else if (bump == SHADER_BUMP_DY)
4030  compiler.parameter("bump_offset", "dy");
4031  else
4032  compiler.parameter("bump_offset", "center");
4033 
4034  compiler.parameter(this, "from_dupli");
4035  compiler.parameter(this, "attribute");
4036  compiler.add(this, "node_uv_map");
4037 }
4038 
4039 /* Light Path */
4040 
4042 {
4043  NodeType *type = NodeType::add("light_path", create, NodeType::SHADER);
4044 
4045  SOCKET_OUT_FLOAT(is_camera_ray, "Is Camera Ray");
4046  SOCKET_OUT_FLOAT(is_shadow_ray, "Is Shadow Ray");
4047  SOCKET_OUT_FLOAT(is_diffuse_ray, "Is Diffuse Ray");
4048  SOCKET_OUT_FLOAT(is_glossy_ray, "Is Glossy Ray");
4049  SOCKET_OUT_FLOAT(is_singular_ray, "Is Singular Ray");
4050  SOCKET_OUT_FLOAT(is_reflection_ray, "Is Reflection Ray");
4051  SOCKET_OUT_FLOAT(is_transmission_ray, "Is Transmission Ray");
4052  SOCKET_OUT_FLOAT(is_volume_scatter_ray, "Is Volume Scatter Ray");
4053  SOCKET_OUT_FLOAT(ray_length, "Ray Length");
4054  SOCKET_OUT_FLOAT(ray_depth, "Ray Depth");
4055  SOCKET_OUT_FLOAT(diffuse_depth, "Diffuse Depth");
4056  SOCKET_OUT_FLOAT(glossy_depth, "Glossy Depth");
4057  SOCKET_OUT_FLOAT(transparent_depth, "Transparent Depth");
4058  SOCKET_OUT_FLOAT(transmission_depth, "Transmission Depth");
4059 
4060  return type;
4061 }
4062 
4063 LightPathNode::LightPathNode() : ShaderNode(get_node_type())
4064 {
4065 }
4066 
4067 void LightPathNode::compile(SVMCompiler &compiler)
4068 {
4069  ShaderOutput *out;
4070 
4071  out = output("Is Camera Ray");
4072  if (!out->links.empty()) {
4073  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_camera, compiler.stack_assign(out));
4074  }
4075 
4076  out = output("Is Shadow Ray");
4077  if (!out->links.empty()) {
4078  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_shadow, compiler.stack_assign(out));
4079  }
4080 
4081  out = output("Is Diffuse Ray");
4082  if (!out->links.empty()) {
4083  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_diffuse, compiler.stack_assign(out));
4084  }
4085 
4086  out = output("Is Glossy Ray");
4087  if (!out->links.empty()) {
4088  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_glossy, compiler.stack_assign(out));
4089  }
4090 
4091  out = output("Is Singular Ray");
4092  if (!out->links.empty()) {
4093  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_singular, compiler.stack_assign(out));
4094  }
4095 
4096  out = output("Is Reflection Ray");
4097  if (!out->links.empty()) {
4098  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_reflection, compiler.stack_assign(out));
4099  }
4100 
4101  out = output("Is Transmission Ray");
4102  if (!out->links.empty()) {
4103  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, compiler.stack_assign(out));
4104  }
4105 
4106  out = output("Is Volume Scatter Ray");
4107  if (!out->links.empty()) {
4108  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_volume_scatter, compiler.stack_assign(out));
4109  }
4110 
4111  out = output("Ray Length");
4112  if (!out->links.empty()) {
4113  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_length, compiler.stack_assign(out));
4114  }
4115 
4116  out = output("Ray Depth");
4117  if (!out->links.empty()) {
4118  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, compiler.stack_assign(out));
4119  }
4120 
4121  out = output("Diffuse Depth");
4122  if (!out->links.empty()) {
4123  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_diffuse, compiler.stack_assign(out));
4124  }
4125 
4126  out = output("Glossy Depth");
4127  if (!out->links.empty()) {
4128  compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_glossy, compiler.stack_assign(out));
4129  }
4130 
4131  out = output("Transparent Depth");
4132  if (!out->links.empty()) {
4134  }
4135 
4136  out = output("Transmission Depth");
4137  if (!out->links.empty()) {
4139  }
4140 }
4141 
4142 void LightPathNode::compile(OSLCompiler &compiler)
4143 {
4144  compiler.add(this, "node_light_path");
4145 }
4146 
4147 /* Light Falloff */
4148 
4150 {
4151  NodeType *type = NodeType::add("light_falloff", create, NodeType::SHADER);
4152 
4153  SOCKET_IN_FLOAT(strength, "Strength", 100.0f);
4154  SOCKET_IN_FLOAT(smooth, "Smooth", 0.0f);
4155 
4156  SOCKET_OUT_FLOAT(quadratic, "Quadratic");
4157  SOCKET_OUT_FLOAT(linear, "Linear");
4158  SOCKET_OUT_FLOAT(constant, "Constant");
4159 
4160  return type;
4161 }
4162 
4163 LightFalloffNode::LightFalloffNode() : ShaderNode(get_node_type())
4164 {
4165 }
4166 
4167 void LightFalloffNode::compile(SVMCompiler &compiler)
4168 {
4169  ShaderInput *strength_in = input("Strength");
4170  ShaderInput *smooth_in = input("Smooth");
4171 
4172  ShaderOutput *out = output("Quadratic");
4173  if (!out->links.empty()) {
4174  compiler.add_node(NODE_LIGHT_FALLOFF,
4176  compiler.encode_uchar4(compiler.stack_assign(strength_in),
4177  compiler.stack_assign(smooth_in),
4178  compiler.stack_assign(out)));
4179  }
4180 
4181  out = output("Linear");
4182  if (!out->links.empty()) {
4183  compiler.add_node(NODE_LIGHT_FALLOFF,
4185  compiler.encode_uchar4(compiler.stack_assign(strength_in),
4186  compiler.stack_assign(smooth_in),
4187  compiler.stack_assign(out)));
4188  }
4189 
4190  out = output("Constant");
4191  if (!out->links.empty()) {
4192  compiler.add_node(NODE_LIGHT_FALLOFF,
4194  compiler.encode_uchar4(compiler.stack_assign(strength_in),
4195  compiler.stack_assign(smooth_in),
4196  compiler.stack_assign(out)));
4197  }
4198 }
4199 
4200 void LightFalloffNode::compile(OSLCompiler &compiler)
4201 {
4202  compiler.add(this, "node_light_falloff");
4203 }
4204 
4205 /* Object Info */
4206 
4208 {
4209  NodeType *type = NodeType::add("object_info", create, NodeType::SHADER);
4210 
4211  SOCKET_OUT_VECTOR(location, "Location");
4212  SOCKET_OUT_COLOR(color, "Color");
4213  SOCKET_OUT_FLOAT(object_index, "Object Index");
4214  SOCKET_OUT_FLOAT(material_index, "Material Index");
4215  SOCKET_OUT_FLOAT(random, "Random");
4216 
4217  return type;
4218 }
4219 
4220 ObjectInfoNode::ObjectInfoNode() : ShaderNode(get_node_type())
4221 {
4222 }
4223 
4224 void ObjectInfoNode::compile(SVMCompiler &compiler)
4225 {
4226  ShaderOutput *out = output("Location");
4227  if (!out->links.empty()) {
4228  compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_LOCATION, compiler.stack_assign(out));
4229  }
4230 
4231  out = output("Color");
4232  if (!out->links.empty()) {
4233  compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_COLOR, compiler.stack_assign(out));
4234  }
4235 
4236  out = output("Object Index");
4237  if (!out->links.empty()) {
4238  compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_INDEX, compiler.stack_assign(out));
4239  }
4240 
4241  out = output("Material Index");
4242  if (!out->links.empty()) {
4243  compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_MAT_INDEX, compiler.stack_assign(out));
4244  }
4245 
4246  out = output("Random");
4247  if (!out->links.empty()) {
4248  compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_RANDOM, compiler.stack_assign(out));
4249  }
4250 }
4251 
4252 void ObjectInfoNode::compile(OSLCompiler &compiler)
4253 {
4254  compiler.add(this, "node_object_info");
4255 }
4256 
4257 /* Particle Info */
4258 
4260 {
4261  NodeType *type = NodeType::add("particle_info", create, NodeType::SHADER);
4262 
4263  SOCKET_OUT_FLOAT(index, "Index");
4264  SOCKET_OUT_FLOAT(random, "Random");
4265  SOCKET_OUT_FLOAT(age, "Age");
4266  SOCKET_OUT_FLOAT(lifetime, "Lifetime");
4267  SOCKET_OUT_POINT(location, "Location");
4268 #if 0 /* not yet supported */
4269  SOCKET_OUT_QUATERNION(rotation, "Rotation");
4270 #endif
4271  SOCKET_OUT_FLOAT(size, "Size");
4272  SOCKET_OUT_VECTOR(velocity, "Velocity");
4273  SOCKET_OUT_VECTOR(angular_velocity, "Angular Velocity");
4274 
4275  return type;
4276 }
4277 
4278 ParticleInfoNode::ParticleInfoNode() : ShaderNode(get_node_type())
4279 {
4280 }
4281 
4283 {
4284  if (!output("Index")->links.empty())
4286  if (!output("Random")->links.empty())
4288  if (!output("Age")->links.empty())
4290  if (!output("Lifetime")->links.empty())
4292  if (!output("Location")->links.empty())
4294 #if 0 /* not yet supported */
4295  if (!output("Rotation")->links.empty())
4297 #endif
4298  if (!output("Size")->links.empty())
4300  if (!output("Velocity")->links.empty())
4302  if (!output("Angular Velocity")->links.empty())
4304 
4306 }
4307 
4308 void ParticleInfoNode::compile(SVMCompiler &compiler)
4309 {
4310  ShaderOutput *out;
4311 
4312  out = output("Index");
4313  if (!out->links.empty()) {
4314  compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, compiler.stack_assign(out));
4315  }
4316 
4317  out = output("Random");
4318  if (!out->links.empty()) {
4320  }
4321 
4322  out = output("Age");
4323  if (!out->links.empty()) {
4324  compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_AGE, compiler.stack_assign(out));
4325  }
4326 
4327  out = output("Lifetime");
4328  if (!out->links.empty()) {
4330  }
4331 
4332  out = output("Location");
4333  if (!out->links.empty()) {
4335  }
4336 
4337  /* quaternion data is not yet supported by Cycles */
4338 #if 0
4339  out = output("Rotation");
4340  if (!out->links.empty()) {
4342  }
4343 #endif
4344 
4345  out = output("Size");
4346  if (!out->links.empty()) {
4347  compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, compiler.stack_assign(out));
4348  }
4349 
4350  out = output("Velocity");
4351  if (!out->links.empty()) {
4353  }
4354 
4355  out = output("Angular Velocity");
4356  if (!out->links.empty()) {
4357  compiler.add_node(
4359  }
4360 }
4361 
4362 void ParticleInfoNode::compile(OSLCompiler &compiler)
4363 {
4364  compiler.add(this, "node_particle_info");
4365 }
4366 
4367 /* Hair Info */
4368 
4370 {
4371  NodeType *type = NodeType::add("hair_info", create, NodeType::SHADER);
4372 
4373  SOCKET_OUT_FLOAT(is_strand, "Is Strand");
4374  SOCKET_OUT_FLOAT(intercept, "Intercept");
4375  SOCKET_OUT_FLOAT(thickness, "Thickness");
4376  SOCKET_OUT_NORMAL(tangent_normal, "Tangent Normal");
4377 #if 0 /*output for minimum hair width transparency - deactivated */
4378  SOCKET_OUT_FLOAT(fade, "Fade");
4379 #endif
4380  SOCKET_OUT_FLOAT(index, "Random");
4381 
4382  return type;
4383 }
4384 
4385 HairInfoNode::HairInfoNode() : ShaderNode(get_node_type())
4386 {
4387 }
4388 
4390 {
4391  if (shader->has_surface) {
4392  ShaderOutput *intercept_out = output("Intercept");
4393 
4394  if (!intercept_out->links.empty())
4396 
4397  if (!output("Random")->links.empty())
4399  }
4400 
4402 }
4403 
4404 void HairInfoNode::compile(SVMCompiler &compiler)
4405 {
4406  ShaderOutput *out;
4407 
4408  out = output("Is Strand");
4409  if (!out->links.empty()) {
4411  }
4412 
4413  out = output("Intercept");
4414  if (!out->links.empty()) {
4415  int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT);
4416  compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
4417  }
4418 
4419  out = output("Thickness");
4420  if (!out->links.empty()) {
4422  }
4423 
4424  out = output("Tangent Normal");
4425  if (!out->links.empty()) {
4427  }
4428 
4429  /*out = output("Fade");
4430  if(!out->links.empty()) {
4431  compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out));
4432  }*/
4433 
4434  out = output("Random");
4435  if (!out->links.empty()) {
4436  int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM);
4437  compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
4438  }
4439 }
4440 
4441 void HairInfoNode::compile(OSLCompiler &compiler)
4442 {
4443  compiler.add(this, "node_hair_info");
4444 }
4445 
4446 /* Volume Info */
4447 
4449 {
4450  NodeType *type = NodeType::add("volume_info", create, NodeType::SHADER);
4451 
4452  SOCKET_OUT_COLOR(color, "Color");
4453  SOCKET_OUT_FLOAT(density, "Density");
4454  SOCKET_OUT_FLOAT(flame, "Flame");
4455  SOCKET_OUT_FLOAT(temperature, "Temperature");
4456 
4457  return type;
4458 }
4459 
4460 VolumeInfoNode::VolumeInfoNode() : ShaderNode(get_node_type())
4461 {
4462 }
4463 
4464 /* The requested attributes are not updated after node expansion.
4465  * So we explicitly request the required attributes.
4466  */
4468 {
4469  if (shader->has_volume) {
4470  if (!output("Color")->links.empty()) {
4472  }
4473  if (!output("Density")->links.empty()) {
4475  }
4476  if (!output("Flame")->links.empty()) {
4478  }
4479  if (!output("Temperature")->links.empty()) {
4481  }
4483  }
4485 }
4486 
4488 {
4489  ShaderOutput *color_out = output("Color");
4490  if (!color_out->links.empty()) {
4491  AttributeNode *attr = graph->create_node<AttributeNode>();
4492  attr->set_attribute(ustring("color"));
4493  graph->add(attr);
4494  graph->relink(color_out, attr->output("Color"));
4495  }
4496 
4497  ShaderOutput *density_out = output("Density");
4498  if (!density_out->links.empty()) {
4499  AttributeNode *attr = graph->create_node<AttributeNode>();
4500  attr->set_attribute(ustring("density"));
4501  graph->add(attr);
4502  graph->relink(density_out, attr->output("Fac"));
4503  }
4504 
4505  ShaderOutput *flame_out = output("Flame");
4506  if (!flame_out->links.empty()) {
4507  AttributeNode *attr = graph->create_node<AttributeNode>();
4508  attr->set_attribute(ustring("flame"));
4509  graph->add(attr);
4510  graph->relink(flame_out, attr->output("Fac"));
4511  }
4512 
4513  ShaderOutput *temperature_out = output("Temperature");
4514  if (!temperature_out->links.empty()) {
4515  AttributeNode *attr = graph->create_node<AttributeNode>();
4516  attr->set_attribute(ustring("temperature"));
4517  graph->add(attr);
4518  graph->relink(temperature_out, attr->output("Fac"));
4519  }
4520 }
4521 
4523 {
4524 }
4525 
4527 {
4528 }
4529 
4531 {
4532  NodeType *type = NodeType::add("vertex_color", create, NodeType::SHADER);
4533 
4534  SOCKET_STRING(layer_name, "Layer Name", ustring());
4535  SOCKET_OUT_COLOR(color, "Color");
4536  SOCKET_OUT_FLOAT(alpha, "Alpha");
4537 
4538  return type;
4539 }
4540 
4541 VertexColorNode::VertexColorNode() : ShaderNode(get_node_type())
4542 {
4543 }
4544 
4546 {
4547  if (!(output("Color")->links.empty() && output("Alpha")->links.empty())) {
4548  if (layer_name != "")
4549  attributes->add_standard(layer_name);
4550  else
4552  }
4554 }
4555 
4556 void VertexColorNode::compile(SVMCompiler &compiler)
4557 {
4558  ShaderOutput *color_out = output("Color");
4559  ShaderOutput *alpha_out = output("Alpha");
4560  int layer_id = 0;
4561 
4562  if (layer_name != "") {
4563  layer_id = compiler.attribute(layer_name);
4564  }
4565  else {
4566  layer_id = compiler.attribute(ATTR_STD_VERTEX_COLOR);
4567  }
4568 
4570 
4571  if (bump == SHADER_BUMP_DX)
4573  else if (bump == SHADER_BUMP_DY)
4575  else {
4577  }
4578 
4579  compiler.add_node(
4580  node, layer_id, compiler.stack_assign(color_out), compiler.stack_assign(alpha_out));
4581 }
4582 
4583 void VertexColorNode::compile(OSLCompiler &compiler)
4584 {
4585  if (bump == SHADER_BUMP_DX) {
4586  compiler.parameter("bump_offset", "dx");
4587  }
4588  else if (bump == SHADER_BUMP_DY) {
4589  compiler.parameter("bump_offset", "dy");
4590  }
4591  else {
4592  compiler.parameter("bump_offset", "center");
4593  }
4594 
4595  if (layer_name.empty()) {
4596  compiler.parameter("layer_name", ustring("geom:vertex_color"));
4597  }
4598  else {
4599  if (Attribute::name_standard(layer_name.c_str()) != ATTR_STD_NONE) {
4600  compiler.parameter("name", (string("geom:") + layer_name.c_str()).c_str());
4601  }
4602  else {
4603  compiler.parameter("layer_name", layer_name.c_str());
4604  }
4605  }
4606 
4607  compiler.add(this, "node_vertex_color");
4608 }
4609 
4610 /* Value */
4611 
4613 {
4614  NodeType *type = NodeType::add("value", create, NodeType::SHADER);
4615 
4616  SOCKET_FLOAT(value, "Value", 0.0f);
4617  SOCKET_OUT_FLOAT(value, "Value");
4618 
4619  return type;
4620 }
4621 
4622 ValueNode::ValueNode() : ShaderNode(get_node_type())
4623 {
4624 }
4625 
4627 {
4628  folder.make_constant(value);
4629 }
4630 
4631 void ValueNode::compile(SVMCompiler &compiler)
4632 {
4633  ShaderOutput *val_out = output("Value");
4634 
4635  compiler.add_node(NODE_VALUE_F, __float_as_int(value), compiler.stack_assign(val_out));
4636 }
4637 
4638 void ValueNode::compile(OSLCompiler &compiler)
4639 {
4640  compiler.parameter("value_value", value);
4641  compiler.add(this, "node_value");
4642 }
4643 
4644 /* Color */
4645 
4647 {
4648  NodeType *type = NodeType::add("color", create, NodeType::SHADER);
4649 
4650  SOCKET_COLOR(value, "Value", zero_float3());
4651  SOCKET_OUT_COLOR(color, "Color");
4652 
4653  return type;
4654 }
4655 
4656 ColorNode::ColorNode() : ShaderNode(get_node_type())
4657 {
4658 }
4659 
4661 {
4662  folder.make_constant(value);
4663 }
4664 
4665 void ColorNode::compile(SVMCompiler &compiler)
4666 {
4667  ShaderOutput *color_out = output("Color");
4668 
4669  if (!color_out->links.empty()) {
4670  compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
4671  compiler.add_node(NODE_VALUE_V, value);
4672  }
4673 }
4674 
4675 void ColorNode::compile(OSLCompiler &compiler)
4676 {
4677  compiler.parameter_color("color_value", value);
4678 
4679  compiler.add(this, "node_value");
4680 }
4681 
4682 /* Add Closure */
4683 
4685 {
4686  NodeType *type = NodeType::add("add_closure", create, NodeType::SHADER);
4687 
4688  SOCKET_IN_CLOSURE(closure1, "Closure1");
4689  SOCKET_IN_CLOSURE(closure2, "Closure2");
4690  SOCKET_OUT_CLOSURE(closure, "Closure");
4691 
4692  return type;
4693 }
4694 
4695 AddClosureNode::AddClosureNode() : ShaderNode(get_node_type())
4696 {
4697  special_type = SHADER_SPECIAL_TYPE_COMBINE_CLOSURE;
4698 }
4699 
4700 void AddClosureNode::compile(SVMCompiler & /*compiler*/)
4701 {
4702  /* handled in the SVM compiler */
4703 }
4704 
4705 void AddClosureNode::compile(OSLCompiler &compiler)
4706 {
4707  compiler.add(this, "node_add_closure");
4708 }
4709 
4711 {
4712  ShaderInput *closure1_in = input("Closure1");
4713  ShaderInput *closure2_in = input("Closure2");
4714 
4715  /* remove useless add closures nodes */
4716  if (!closure1_in->link) {
4717  folder.bypass_or_discard(closure2_in);
4718  }
4719  else if (!closure2_in->link) {
4720  folder.bypass_or_discard(closure1_in);
4721  }
4722 }
4723 
4724 /* Mix Closure */
4725 
4727 {
4728  NodeType *type = NodeType::add("mix_closure", create, NodeType::SHADER);
4729 
4730  SOCKET_IN_FLOAT(fac, "Fac", 0.5f);
4731  SOCKET_IN_CLOSURE(closure1, "Closure1");
4732  SOCKET_IN_CLOSURE(closure2, "Closure2");
4733 
4734  SOCKET_OUT_CLOSURE(closure, "Closure");
4735 
4736  return type;
4737 }
4738 
4739 MixClosureNode::MixClosureNode() : ShaderNode(get_node_type())
4740 {
4741  special_type = SHADER_SPECIAL_TYPE_COMBINE_CLOSURE;
4742 }
4743 
4744 void MixClosureNode::compile(SVMCompiler & /*compiler*/)
4745 {
4746  /* handled in the SVM compiler */
4747 }
4748 
4749 void MixClosureNode::compile(OSLCompiler &compiler)
4750 {
4751  compiler.add(this, "node_mix_closure");
4752 }
4753 
4755 {
4756  ShaderInput *fac_in = input("Fac");
4757  ShaderInput *closure1_in = input("Closure1");
4758  ShaderInput *closure2_in = input("Closure2");
4759 
4760  /* remove useless mix closures nodes */
4761  if (closure1_in->link == closure2_in->link) {
4762  folder.bypass_or_discard(closure1_in);
4763  }
4764  /* remove unused mix closure input when factor is 0.0 or 1.0
4765  * check for closure links and make sure factor link is disconnected */
4766  else if (!fac_in->link) {
4767  /* factor 0.0 */
4768  if (fac <= 0.0f) {
4769  folder.bypass_or_discard(closure1_in);
4770  }
4771  /* factor 1.0 */
4772  else if (fac >= 1.0f) {
4773  folder.bypass_or_discard(closure2_in);
4774  }
4775  }
4776 }
4777 
4778 /* Mix Closure */
4779 
4781 {
4782  NodeType *type = NodeType::add("mix_closure_weight", create, NodeType::SHADER);
4783 
4784  SOCKET_IN_FLOAT(weight, "Weight", 1.0f);
4785  SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
4786 
4787  SOCKET_OUT_FLOAT(weight1, "Weight1");
4788  SOCKET_OUT_FLOAT(weight2, "Weight2");
4789 
4790  return type;
4791 }
4792 
4793 MixClosureWeightNode::MixClosureWeightNode() : ShaderNode(get_node_type())
4794 {
4795 }
4796 
4798 {
4799  ShaderInput *weight_in = input("Weight");
4800  ShaderInput *fac_in = input("Fac");
4801  ShaderOutput *weight1_out = output("Weight1");
4802  ShaderOutput *weight2_out = output("Weight2");
4803 
4804  compiler.add_node(NODE_MIX_CLOSURE,
4805  compiler.encode_uchar4(compiler.stack_assign(fac_in),
4806  compiler.stack_assign(weight_in),
4807  compiler.stack_assign(weight1_out),
4808  compiler.stack_assign(weight2_out)));
4809 }
4810 
4811 void MixClosureWeightNode::compile(OSLCompiler & /*compiler*/)
4812 {
4813  assert(0);
4814 }
4815 
4816 /* Invert */
4817 
4819 {
4820  NodeType *type = NodeType::add("invert", create, NodeType::SHADER);
4821 
4822  SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
4823  SOCKET_IN_COLOR(color, "Color", zero_float3());
4824 
4825  SOCKET_OUT_COLOR(color, "Color");
4826 
4827  return type;
4828 }
4829 
4830 InvertNode::InvertNode() : ShaderNode(get_node_type())
4831 {
4832 }
4833 
4835 {
4836  ShaderInput *fac_in = input("Fac");
4837  ShaderInput *color_in = input("Color");
4838 
4839  if (!fac_in->link) {
4840  /* evaluate fully constant node */
4841  if (!color_in->link) {
4842  folder.make_constant(interp(color, one_float3() - color, fac));
4843  }
4844  /* remove no-op node */
4845  else if (fac == 0.0f) {
4846  folder.bypass(color_in->link);
4847  }
4848  }
4849 }
4850 
4851 void InvertNode::compile(SVMCompiler &compiler)
4852 {
4853  ShaderInput *fac_in = input("Fac");
4854  ShaderInput *color_in = input("Color");
4855  ShaderOutput *color_out = output("Color");
4856 
4857  compiler.add_node(NODE_INVERT,
4858  compiler.stack_assign(fac_in),
4859  compiler.stack_assign(color_in),
4860  compiler.stack_assign(color_out));
4861 }
4862 
4863 void InvertNode::compile(OSLCompiler &compiler)
4864 {
4865  compiler.add(this, "node_invert");
4866 }
4867 
4868 /* Mix */
4869 
4871 {
4872  NodeType *type = NodeType::add("mix", create, NodeType::SHADER);
4873 
4874  static NodeEnum type_enum;
4875  type_enum.insert("mix", NODE_MIX_BLEND);
4876  type_enum.insert("add", NODE_MIX_ADD);
4877  type_enum.insert("multiply", NODE_MIX_MUL);
4878  type_enum.insert("screen", NODE_MIX_SCREEN);
4879  type_enum.insert("overlay", NODE_MIX_OVERLAY);
4880  type_enum.insert("subtract", NODE_MIX_SUB);
4881  type_enum.insert("divide", NODE_MIX_DIV);
4882  type_enum.insert("difference", NODE_MIX_DIFF);
4883  type_enum.insert("darken", NODE_MIX_DARK);
4884  type_enum.insert("lighten", NODE_MIX_LIGHT);
4885  type_enum.insert("dodge", NODE_MIX_DODGE);
4886  type_enum.insert("burn", NODE_MIX_BURN);
4887  type_enum.insert("hue", NODE_MIX_HUE);
4888  type_enum.insert("saturation", NODE_MIX_SAT);
4889  type_enum.insert("value", NODE_MIX_VAL);
4890  type_enum.insert("color", NODE_MIX_COLOR);
4891  type_enum.insert("soft_light", NODE_MIX_SOFT);
4892  type_enum.insert("linear_light", NODE_MIX_LINEAR);
4893  SOCKET_ENUM(mix_type, "Type", type_enum, NODE_MIX_BLEND);
4894 
4895  SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
4896 
4897  SOCKET_IN_FLOAT(fac, "Fac", 0.5f);
4898  SOCKET_IN_COLOR(color1, "Color1", zero_float3());
4899  SOCKET_IN_COLOR(color2, "Color2", zero_float3());
4900 
4901  SOCKET_OUT_COLOR(color, "Color");
4902 
4903  return type;
4904 }
4905 
4906 MixNode::MixNode() : ShaderNode(get_node_type())
4907 {
4908 }
4909 
4910 void MixNode::compile(SVMCompiler &compiler)
4911 {
4912  ShaderInput *fac_in = input("Fac");
4913  ShaderInput *color1_in = input("Color1");
4914  ShaderInput *color2_in = input("Color2");
4915  ShaderOutput *color_out = output("Color");
4916 
4917  compiler.add_node(NODE_MIX,
4918  compiler.stack_assign(fac_in),
4919  compiler.stack_assign(color1_in),
4920  compiler.stack_assign(color2_in));
4921  compiler.add_node(NODE_MIX, mix_type, compiler.stack_assign(color_out));
4922 
4923  if (use_clamp) {
4924  compiler.add_node(NODE_MIX, 0, compiler.stack_assign(color_out));
4925  compiler.add_node(NODE_MIX, NODE_MIX_CLAMP, compiler.stack_assign(color_out));
4926  }
4927 }
4928 
4929 void MixNode::compile(OSLCompiler &compiler)
4930 {
4931  compiler.parameter(this, "mix_type");
4932  compiler.parameter(this, "use_clamp");
4933  compiler.add(this, "node_mix");
4934 }
4935 
4937 {
4938  if (folder.all_inputs_constant()) {
4939  folder.make_constant_clamp(svm_mix(mix_type, fac, color1, color2), use_clamp);
4940  }
4941  else {
4942  folder.fold_mix(mix_type, use_clamp);
4943  }
4944 }
4945 
4946 /* Combine RGB */
4947 
4949 {
4950  NodeType *type = NodeType::add("combine_rgb", create, NodeType::SHADER);
4951 
4952  SOCKET_IN_FLOAT(r, "R", 0.0f);
4953  SOCKET_IN_FLOAT(g, "G", 0.0f);
4954  SOCKET_IN_FLOAT(b, "B", 0.0f);
4955 
4956  SOCKET_OUT_COLOR(image, "Image");
4957 
4958  return type;
4959 }
4960 
4961 CombineRGBNode::CombineRGBNode() : ShaderNode(get_node_type())
4962 {
4963 }
4964 
4966 {
4967  if (folder.all_inputs_constant()) {
4968  folder.make_constant(make_float3(r, g, b));
4969  }
4970 }
4971 
4972 void CombineRGBNode::compile(SVMCompiler &compiler)
4973 {
4974  ShaderInput *red_in = input("R");
4975  ShaderInput *green_in = input("G");
4976  ShaderInput *blue_in = input("B");
4977  ShaderOutput *color_out = output("Image");
4978 
4979  compiler.add_node(
4980  NODE_COMBINE_VECTOR, compiler.stack_assign(red_in), 0, compiler.stack_assign(color_out));
4981 
4982  compiler.add_node(
4983  NODE_COMBINE_VECTOR, compiler.stack_assign(green_in), 1, compiler.stack_assign(color_out));
4984 
4985  compiler.add_node(
4986  NODE_COMBINE_VECTOR, compiler.stack_assign(blue_in), 2, compiler.stack_assign(color_out));
4987 }
4988 
4989 void CombineRGBNode::compile(OSLCompiler &compiler)
4990 {
4991  compiler.add(this, "node_combine_rgb");
4992 }
4993 
4994 /* Combine XYZ */
4995 
4997 {
4998  NodeType *type = NodeType::add("combine_xyz", create, NodeType::SHADER);
4999 
5000  SOCKET_IN_FLOAT(x, "X", 0.0f);
5001  SOCKET_IN_FLOAT(y, "Y", 0.0f);
5002  SOCKET_IN_FLOAT(z, "Z", 0.0f);
5003 
5004  SOCKET_OUT_VECTOR(vector, "Vector");
5005 
5006  return type;
5007 }
5008 
5009 CombineXYZNode::CombineXYZNode() : ShaderNode(get_node_type())
5010 {
5011 }
5012 
5014 {
5015  if (folder.all_inputs_constant()) {
5016  folder.make_constant(make_float3(x, y, z));
5017  }
5018 }
5019 
5020 void CombineXYZNode::compile(SVMCompiler &compiler)
5021 {
5022  ShaderInput *x_in = input("X");
5023  ShaderInput *y_in = input("Y");
5024  ShaderInput *z_in = input("Z");
5025  ShaderOutput *vector_out = output("Vector");
5026 
5027  compiler.add_node(
5028  NODE_COMBINE_VECTOR, compiler.stack_assign(x_in), 0, compiler.stack_assign(vector_out));
5029 
5030  compiler.add_node(
5031  NODE_COMBINE_VECTOR, compiler.stack_assign(y_in), 1, compiler.stack_assign(vector_out));
5032 
5033  compiler.add_node(
5034  NODE_COMBINE_VECTOR, compiler.stack_assign(z_in), 2, compiler.stack_assign(vector_out));
5035 }
5036 
5037 void CombineXYZNode::compile(OSLCompiler &compiler)
5038 {
5039  compiler.add(this, "node_combine_xyz");
5040 }
5041 
5042 /* Combine HSV */
5043 
5045 {
5046  NodeType *type = NodeType::add("combine_hsv", create, NodeType::SHADER);
5047 
5048  SOCKET_IN_FLOAT(h, "H", 0.0f);
5049  SOCKET_IN_FLOAT(s, "S", 0.0f);
5050  SOCKET_IN_FLOAT(v, "V", 0.0f);
5051 
5052  SOCKET_OUT_COLOR(color, "Color");
5053 
5054  return type;
5055 }
5056 
5057 CombineHSVNode::CombineHSVNode() : ShaderNode(get_node_type())
5058 {
5059 }
5060 
5062 {
5063  if (folder.all_inputs_constant()) {
5064  folder.make_constant(hsv_to_rgb(make_float3(h, s, v)));
5065  }
5066 }
5067 
5068 void CombineHSVNode::compile(SVMCompiler &compiler)
5069 {
5070  ShaderInput *hue_in = input("H");
5071  ShaderInput *saturation_in = input("S");
5072  ShaderInput *value_in = input("V");
5073  ShaderOutput *color_out = output("Color");
5074 
5075  compiler.add_node(NODE_COMBINE_HSV,
5076  compiler.stack_assign(hue_in),
5077  compiler.stack_assign(saturation_in),
5078  compiler.stack_assign(value_in));
5079  compiler.add_node(NODE_COMBINE_HSV, compiler.stack_assign(color_out));
5080 }
5081 
5082 void CombineHSVNode::compile(OSLCompiler &compiler)
5083 {
5084  compiler.add(this, "node_combine_hsv");
5085 }
5086 
5087 /* Gamma */
5088 
5090 {
5091  NodeType *type = NodeType::add("gamma", create, NodeType::SHADER);
5092 
5093  SOCKET_IN_COLOR(color, "Color", zero_float3());
5094  SOCKET_IN_FLOAT(gamma, "Gamma", 1.0f);
5095  SOCKET_OUT_COLOR(color, "Color");
5096 
5097  return type;
5098 }
5099 
5100 GammaNode::GammaNode() : ShaderNode(get_node_type())
5101 {
5102 }
5103 
5105 {
5106  if (folder.all_inputs_constant()) {
5107  folder.make_constant(svm_math_gamma_color(color, gamma));
5108  }
5109  else {
5110  ShaderInput *color_in = input("Color");
5111  ShaderInput *gamma_in = input("Gamma");
5112 
5113  /* 1 ^ X == X ^ 0 == 1 */
5114  if (folder.is_one(color_in) || folder.is_zero(gamma_in)) {
5115  folder.make_one();
5116  }
5117  /* X ^ 1 == X */
5118  else if (folder.is_one(gamma_in)) {
5119  folder.try_bypass_or_make_constant(color_in, false);
5120  }
5121  }
5122 }
5123 
5124 void GammaNode::compile(SVMCompiler &compiler)
5125 {
5126  ShaderInput *color_in = input("Color");
5127  ShaderInput *gamma_in = input("Gamma");
5128  ShaderOutput *color_out = output("Color");
5129 
5130  compiler.add_node(NODE_GAMMA,
5131  compiler.stack_assign(gamma_in),
5132  compiler.stack_assign(color_in),
5133  compiler.stack_assign(color_out));
5134 }
5135 
5136 void GammaNode::compile(OSLCompiler &compiler)
5137 {
5138  compiler.add(this, "node_gamma");
5139 }
5140 
5141 /* Bright Contrast */
5142 
5144 {
5145  NodeType *type = NodeType::add("brightness_contrast", create, NodeType::SHADER);
5146 
5147  SOCKET_IN_COLOR(color, "Color", zero_float3());
5148  SOCKET_IN_FLOAT(bright, "Bright", 0.0f);
5149  SOCKET_IN_FLOAT(contrast, "Contrast", 0.0f);
5150 
5151  SOCKET_OUT_COLOR(color, "Color");
5152 
5153  return type;
5154 }
5155 
5156 BrightContrastNode::BrightContrastNode() : ShaderNode(get_node_type())
5157 {
5158 }
5159 
5161 {
5162  if (folder.all_inputs_constant()) {
5163  folder.make_constant(svm_brightness_contrast(color, bright, contrast));
5164  }
5165 }
5166 
5168 {
5169  ShaderInput *color_in = input("Color");
5170  ShaderInput *bright_in = input("Bright");
5171  ShaderInput *contrast_in = input("Contrast");
5172  ShaderOutput *color_out = output("Color");
5173 
5174  compiler.add_node(NODE_BRIGHTCONTRAST,
5175  compiler.stack_assign(color_in),
5176  compiler.stack_assign(color_out),
5177  compiler.encode_uchar4(compiler.stack_assign(bright_in),
5178  compiler.stack_assign(contrast_in)));
5179 }
5180 
5182 {
5183  compiler.add(this, "node_brightness");
5184 }
5185 
5186 /* Separate RGB */
5187 
5189 {
5190  NodeType *type = NodeType::add("separate_rgb", create, NodeType::SHADER);
5191 
5192  SOCKET_IN_COLOR(color, "Image", zero_float3());
5193 
5194  SOCKET_OUT_FLOAT(r, "R");
5195  SOCKET_OUT_FLOAT(g, "G");
5196  SOCKET_OUT_FLOAT(b, "B");
5197 
5198  return type;
5199 }
5200 
5201 SeparateRGBNode::SeparateRGBNode() : ShaderNode(get_node_type())
5202 {
5203 }
5204 
5206 {
5207  if (folder.all_inputs_constant()) {
5208  for (int channel = 0; channel < 3; channel++) {
5209  if (outputs[channel] == folder.output) {
5210  folder.make_constant(color[channel]);
5211  return;
5212  }
5213  }
5214  }
5215 }
5216 
5217 void SeparateRGBNode::compile(SVMCompiler &compiler)
5218 {
5219  ShaderInput *color_in = input("Image");
5220  ShaderOutput *red_out = output("R");
5221  ShaderOutput *green_out = output("G");
5222  ShaderOutput *blue_out = output("B");
5223 
5224  compiler.add_node(
5225  NODE_SEPARATE_VECTOR, compiler.stack_assign(color_in), 0, compiler.stack_assign(red_out));
5226 
5227  compiler.add_node(
5228  NODE_SEPARATE_VECTOR, compiler.stack_assign(color_in), 1, compiler.stack_assign(green_out));
5229 
5230  compiler.add_node(
5231  NODE_SEPARATE_VECTOR, compiler.stack_assign(color_in), 2, compiler.stack_assign(blue_out));
5232 }
5233 
5234 void SeparateRGBNode::compile(OSLCompiler &compiler)
5235 {
5236  compiler.add(this, "node_separate_rgb");
5237 }
5238 
5239 /* Separate XYZ */
5240 
5242 {
5243  NodeType *type = NodeType::add("separate_xyz", create, NodeType::SHADER);
5244 
5245  SOCKET_IN_COLOR(vector, "Vector", zero_float3());
5246 
5247  SOCKET_OUT_FLOAT(x, "X");
5248  SOCKET_OUT_FLOAT(y, "Y");
5249  SOCKET_OUT_FLOAT(z, "Z");
5250 
5251  return type;
5252 }
5253 
5254 SeparateXYZNode::SeparateXYZNode() : ShaderNode(get_node_type())
5255 {
5256 }
5257 
5259 {
5260  if (folder.all_inputs_constant()) {
5261  for (int channel = 0; channel < 3; channel++) {
5262  if (outputs[channel] == folder.output) {
5263  folder.make_constant(vector[channel]);
5264  return;
5265  }
5266  }
5267  }
5268 }
5269 
5270 void SeparateXYZNode::compile(SVMCompiler &compiler)
5271 {
5272  ShaderInput *vector_in = input("Vector");
5273  ShaderOutput *x_out = output("X");
5274  ShaderOutput *y_out = output("Y");
5275  ShaderOutput *z_out = output("Z");
5276 
5277  compiler.add_node(
5278  NODE_SEPARATE_VECTOR, compiler.stack_assign(vector_in), 0, compiler.stack_assign(x_out));
5279 
5280  compiler.add_node(
5281  NODE_SEPARATE_VECTOR, compiler.stack_assign(vector_in), 1, compiler.stack_assign(y_out));
5282 
5283  compiler.add_node(
5284  NODE_SEPARATE_VECTOR, compiler.stack_assign(vector_in), 2, compiler.stack_assign(z_out));
5285 }
5286 
5287 void SeparateXYZNode::compile(OSLCompiler &compiler)
5288 {
5289  compiler.add(this, "node_separate_xyz");
5290 }
5291 
5292 /* Separate HSV */
5293 
5295 {
5296  NodeType *type = NodeType::add("separate_hsv", create, NodeType::SHADER);
5297 
5298  SOCKET_IN_COLOR(color, "Color", zero_float3());
5299 
5300  SOCKET_OUT_FLOAT(h, "H");
5301  SOCKET_OUT_FLOAT(s, "S");
5302  SOCKET_OUT_FLOAT(v, "V");
5303 
5304  return type;
5305 }
5306 
5307 SeparateHSVNode::SeparateHSVNode() : ShaderNode(get_node_type())
5308 {
5309 }
5310 
5312 {
5313  if (folder.all_inputs_constant()) {
5314  float3 hsv = rgb_to_hsv(color);
5315 
5316  for (int channel = 0; channel < 3; channel++) {
5317  if (outputs[channel] == folder.output) {
5318  folder.make_constant(hsv[channel]);
5319  return;
5320  }
5321  }
5322  }
5323 }
5324 
5325 void SeparateHSVNode::compile(SVMCompiler &compiler)
5326 {
5327  ShaderInput *color_in = input("Color");
5328  ShaderOutput *hue_out = output("H");
5329  ShaderOutput *saturation_out = output("S");
5330  ShaderOutput *value_out = output("V");
5331 
5332  compiler.add_node(NODE_SEPARATE_HSV,
5333  compiler.stack_assign(color_in),
5334  compiler.stack_assign(hue_out),
5335  compiler.stack_assign(saturation_out));
5336  compiler.add_node(NODE_SEPARATE_HSV, compiler.stack_assign(value_out));
5337 }
5338 
5339 void SeparateHSVNode::compile(OSLCompiler &compiler)
5340 {
5341  compiler.add(this, "node_separate_hsv");
5342 }
5343 
5344 /* Hue Saturation Value */
5345 
5347 {
5348  NodeType *type = NodeType::add("hsv", create, NodeType::SHADER);
5349 
5350  SOCKET_IN_FLOAT(hue, "Hue", 0.5f);
5351  SOCKET_IN_FLOAT(saturation, "Saturation", 1.0f);
5352  SOCKET_IN_FLOAT(value, "Value", 1.0f);
5353  SOCKET_IN_FLOAT(fac, "Fac", 1.0f);
5354  SOCKET_IN_COLOR(color, "Color", zero_float3());
5355 
5356  SOCKET_OUT_COLOR(color, "Color");
5357 
5358  return type;
5359 }
5360 
5361 HSVNode::HSVNode() : ShaderNode(get_node_type())
5362 {
5363 }
5364 
5365 void HSVNode::compile(SVMCompiler &compiler)
5366 {
5367  ShaderInput *hue_in = input("Hue");
5368  ShaderInput *saturation_in = input("Saturation");
5369  ShaderInput *value_in = input("Value");
5370  ShaderInput *fac_in = input("Fac");
5371  ShaderInput *color_in = input("Color");
5372  ShaderOutput *color_out = output("Color");
5373 
5374  compiler.add_node(NODE_HSV,
5375  compiler.encode_uchar4(compiler.stack_assign(color_in),
5376  compiler.stack_assign(fac_in),
5377  compiler.stack_assign(color_out)),
5378  compiler.encode_uchar4(compiler.stack_assign(hue_in),
5379  compiler.stack_assign(saturation_in),
5380  compiler.stack_assign(value_in)));
5381 }
5382 
5383 void HSVNode::compile(OSLCompiler &compiler)
5384 {
5385  compiler.add(this, "node_hsv");
5386 }
5387 
5388 /* Attribute */
5389 
5391 {
5392  NodeType *type = NodeType::add("attribute", create, NodeType::SHADER);
5393 
5394  SOCKET_STRING(attribute, "Attribute", ustring());
5395 
5396  SOCKET_OUT_COLOR(color, "Color");
5397  SOCKET_OUT_VECTOR(vector, "Vector");
5398  SOCKET_OUT_FLOAT(fac, "Fac");
5399  SOCKET_OUT_FLOAT(alpha, "Alpha");
5400 
5401  return type;
5402 }
5403 
5404 AttributeNode::AttributeNode() : ShaderNode(get_node_type())
5405 {
5406 }
5407 
5409 {
5410  ShaderOutput *color_out = output("Color");
5411  ShaderOutput *vector_out = output("Vector");
5412  ShaderOutput *fac_out = output("Fac");
5413  ShaderOutput *alpha_out = output("Alpha");
5414 
5415  if (!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty() ||
5416  !alpha_out->links.empty()) {
5417  attributes->add_standard(attribute);
5418  }
5419 
5420  if (shader->has_volume) {
5422  }
5423 
5425 }
5426 
5427 void AttributeNode::compile(SVMCompiler &compiler)
5428 {
5429  ShaderOutput *color_out = output("Color");
5430  ShaderOutput *vector_out = output("Vector");
5431  ShaderOutput *fac_out = output("Fac");
5432  ShaderOutput *alpha_out = output("Alpha");
5433  ShaderNodeType attr_node = NODE_ATTR;
5434  int attr = compiler.attribute_standard(attribute);
5435 
5436  if (bump == SHADER_BUMP_DX)
5437  attr_node = NODE_ATTR_BUMP_DX;
5438  else if (bump == SHADER_BUMP_DY)
5439  attr_node = NODE_ATTR_BUMP_DY;
5440 
5441  if (!color_out->links.empty() || !vector_out->links.empty()) {
5442  if (!color_out->links.empty()) {
5443  compiler.add_node(
5444  attr_node, attr, compiler.stack_assign(color_out), NODE_ATTR_OUTPUT_FLOAT3);
5445  }
5446  if (!vector_out->links.empty()) {
5447  compiler.add_node(
5448  attr_node, attr, compiler.stack_assign(vector_out), NODE_ATTR_OUTPUT_FLOAT3);
5449  }
5450  }
5451 
5452  if (!fac_out->links.empty()) {
5453  compiler.add_node(attr_node, attr, compiler.stack_assign(fac_out), NODE_ATTR_OUTPUT_FLOAT);
5454  }
5455 
5456  if (!alpha_out->links.empty()) {
5457  compiler.add_node(
5458  attr_node, attr, compiler.stack_assign(alpha_out), NODE_ATTR_OUTPUT_FLOAT_ALPHA);
5459  }
5460 }
5461 
5462 void AttributeNode::compile(OSLCompiler &compiler)
5463 {
5464  if (bump == SHADER_BUMP_DX)
5465  compiler.parameter("bump_offset", "dx");
5466  else if (bump == SHADER_BUMP_DY)
5467  compiler.parameter("bump_offset", "dy");
5468  else
5469  compiler.parameter("bump_offset", "center");
5470 
5471  if (Attribute::name_standard(attribute.c_str()) != ATTR_STD_NONE)
5472  compiler.parameter("name", (string("geom:") + attribute.c_str()).c_str());
5473  else
5474  compiler.parameter("name", attribute.c_str());
5475 
5476  compiler.add(this, "node_attribute");
5477 }
5478 
5479 /* Camera */
5480 
5482 {
5483  NodeType *type = NodeType::add("camera_info", create, NodeType::SHADER);
5484 
5485  SOCKET_OUT_VECTOR(view_vector, "View Vector");
5486  SOCKET_OUT_FLOAT(view_z_depth, "View Z Depth");
5487  SOCKET_OUT_FLOAT(view_distance, "View Distance");
5488 
5489  return type;
5490 }
5491 
5492 CameraNode::CameraNode() : ShaderNode(get_node_type())
5493 {
5494 }
5495 
5496 void CameraNode::compile(SVMCompiler &compiler)
5497 {
5498  ShaderOutput *vector_out = output("View Vector");
5499  ShaderOutput *z_depth_out = output("View Z Depth");
5500  ShaderOutput *distance_out = output("View Distance");
5501 
5502  compiler.add_node(NODE_CAMERA,
5503  compiler.stack_assign(vector_out),
5504  compiler.stack_assign(z_depth_out),
5505  compiler.stack_assign(distance_out));
5506 }
5507 
5508 void CameraNode::compile(OSLCompiler &compiler)
5509 {
5510  compiler.add(this, "node_camera");
5511 }
5512 
5513 /* Fresnel */
5514 
5516 {
5517  NodeType *type = NodeType::add("fresnel", create, NodeType::SHADER);
5518 
5521  SOCKET_IN_FLOAT(IOR, "IOR", 1.45f);
5522 
5523  SOCKET_OUT_FLOAT(fac, "Fac");
5524 
5525  return type;
5526 }
5527 
5528 FresnelNode::FresnelNode() : ShaderNode(get_node_type())
5529 {
5530 }
5531 
5532 void FresnelNode::compile(SVMCompiler &compiler)
5533 {
5534  ShaderInput *normal_in = input("Normal");
5535  ShaderInput *IOR_in = input("IOR");
5536  ShaderOutput *fac_out = output("Fac");
5537 
5538  compiler.add_node(NODE_FRESNEL,
5539  compiler.stack_assign(IOR_in),
5540  __float_as_int(IOR),
5541  compiler.encode_uchar4(compiler.stack_assign_if_linked(normal_in),
5542  compiler.stack_assign(fac_out)));
5543 }
5544 
5545 void FresnelNode::compile(OSLCompiler &compiler)
5546 {
5547  compiler.add(this, "node_fresnel");
5548 }
5549 
5550 /* Layer Weight */
5551 
5553 {
5554  NodeType *type = NodeType::add("layer_weight", create, NodeType::SHADER);
5555 
5558  SOCKET_IN_FLOAT(blend, "Blend", 0.5f);
5559 
5560  SOCKET_OUT_FLOAT(fresnel, "Fresnel");
5561  SOCKET_OUT_FLOAT(facing, "Facing");
5562 
5563  return type;
5564 }
5565 
5566 LayerWeightNode::LayerWeightNode() : ShaderNode(get_node_type())
5567 {
5568 }
5569 
5570 void LayerWeightNode::compile(SVMCompiler &compiler)
5571 {
5572  ShaderInput *normal_in = input("Normal");
5573  ShaderInput *blend_in = input("Blend");
5574  ShaderOutput *fresnel_out = output("Fresnel");
5575  ShaderOutput *facing_out = output("Facing");
5576 
5577  if (!fresnel_out->links.empty()) {
5578  compiler.add_node(NODE_LAYER_WEIGHT,
5579  compiler.stack_assign_if_linked(blend_in),
5582  compiler.stack_assign_if_linked(normal_in),
5583  compiler.stack_assign(fresnel_out)));
5584  }
5585 
5586  if (!facing_out->links.empty()) {
5587  compiler.add_node(NODE_LAYER_WEIGHT,
5588  compiler.stack_assign_if_linked(blend_in),
5591  compiler.stack_assign_if_linked(normal_in),
5592  compiler.stack_assign(facing_out)));
5593  }
5594 }
5595 
5596 void LayerWeightNode::compile(OSLCompiler &compiler)
5597 {
5598  compiler.add(this, "node_layer_weight");
5599 }
5600 
5601 /* Wireframe */
5602 
5604 {
5605  NodeType *type = NodeType::add("wireframe", create, NodeType::SHADER);
5606 
5607  SOCKET_BOOLEAN(use_pixel_size, "Use Pixel Size", false);
5608  SOCKET_IN_FLOAT(size, "Size", 0.01f);
5609  SOCKET_OUT_FLOAT(fac, "Fac");
5610 
5611  return type;
5612 }
5613 
5614 WireframeNode::WireframeNode() : ShaderNode(get_node_type())
5615 {
5616 }
5617 
5618 void WireframeNode::compile(SVMCompiler &compiler)
5619 {
5620  ShaderInput *size_in = input("Size");
5621  ShaderOutput *fac_out = output("Fac");
5623  if (bump == SHADER_BUMP_DX) {
5624  bump_offset = NODE_BUMP_OFFSET_DX;
5625  }
5626  else if (bump == SHADER_BUMP_DY) {
5627  bump_offset = NODE_BUMP_OFFSET_DY;
5628  }
5629  compiler.add_node(NODE_WIREFRAME,
5630  compiler.stack_assign(size_in),
5631  compiler.stack_assign(fac_out),
5632  compiler.encode_uchar4(use_pixel_size, bump_offset, 0, 0));
5633 }
5634 
5635 void WireframeNode::compile(OSLCompiler &compiler)
5636 {
5637  if (bump == SHADER_BUMP_DX) {
5638  compiler.parameter("bump_offset", "dx");
5639  }
5640  else if (bump == SHADER_BUMP_DY) {
5641  compiler.parameter("bump_offset", "dy");
5642  }
5643  else {
5644  compiler.parameter("bump_offset", "center");
5645  }
5646  compiler.parameter(this, "use_pixel_size");
5647  compiler.add(this, "node_wireframe");
5648 }
5649 
5650 /* Wavelength */
5651 
5653 {
5654  NodeType *type = NodeType::add("wavelength", create, NodeType::SHADER);
5655 
5656  SOCKET_IN_FLOAT(wavelength, "Wavelength", 500.0f);
5657  SOCKET_OUT_COLOR(color, "Color");
5658 
5659  return type;
5660 }
5661 
5662 WavelengthNode::WavelengthNode() : ShaderNode(get_node_type())
5663 {
5664 }
5665 
5666 void WavelengthNode::compile(SVMCompiler &compiler)
5667 {
5668  ShaderInput *wavelength_in = input("Wavelength");
5669  ShaderOutput *color_out = output("Color");
5670 
5671  compiler.add_node(
5672  NODE_WAVELENGTH, compiler.stack_assign(wavelength_in), compiler.stack_assign(color_out));
5673 }
5674 
5675 void WavelengthNode::compile(OSLCompiler &compiler)
5676 {
5677  compiler.add(this, "node_wavelength");
5678 }
5679 
5680 /* Blackbody */
5681 
5683 {
5684  NodeType *type = NodeType::add("blackbody", create, NodeType::SHADER);
5685 
5686  SOCKET_IN_FLOAT(temperature, "Temperature", 1200.0f);
5687  SOCKET_OUT_COLOR(color, "Color");
5688 
5689  return type;
5690 }
5691 
5692 BlackbodyNode::BlackbodyNode() : ShaderNode(get_node_type())
5693 {
5694 }
5695 
5697 {
5698  if (folder.all_inputs_constant()) {
5699  folder.make_constant(svm_math_blackbody_color(temperature));
5700  }
5701 }
5702 
5703 void BlackbodyNode::compile(SVMCompiler &compiler)
5704 {
5705  ShaderInput *temperature_in = input("Temperature");
5706  ShaderOutput *color_out = output("Color");
5707 
5708  compiler.add_node(
5709  NODE_BLACKBODY, compiler.stack_assign(temperature_in), compiler.stack_assign(color_out));
5710 }
5711 
5712 void BlackbodyNode::compile(OSLCompiler &compiler)
5713 {
5714  compiler.add(this, "node_blackbody");
5715 }
5716 
5717 /* Output */
5718 
5720 {
5721  NodeType *type = NodeType::add("output", create, NodeType::SHADER);
5722 
5723  SOCKET_IN_CLOSURE(surface, "Surface");
5724  SOCKET_IN_CLOSURE(volume, "Volume");
5725  SOCKET_IN_VECTOR(displacement, "Displacement", zero_float3());
5726  SOCKET_IN_NORMAL(normal, "Normal", zero_float3());
5727 
5728  return type;
5729 }
5730 
5731 OutputNode::OutputNode() : ShaderNode(get_node_type())
5732 {
5733  special_type = SHADER_SPECIAL_TYPE_OUTPUT;
5734 }
5735 
5736 void OutputNode::compile(SVMCompiler &compiler)
5737 {
5738  if (compiler.output_type() == SHADER_TYPE_DISPLACEMENT) {
5739  ShaderInput *displacement_in = input("Displacement");
5740 
5741  if (displacement_in->link) {
5742  compiler.add_node(NODE_SET_DISPLACEMENT, compiler.stack_assign(displacement_in));
5743  }
5744  }
5745 }
5746 
5747 void OutputNode::compile(OSLCompiler &compiler)
5748 {
5749  if (compiler.output_type() == SHADER_TYPE_SURFACE)
5750  compiler.add(this, "node_output_surface");
5751  else if (compiler.output_type() == SHADER_TYPE_VOLUME)
5752  compiler.add(this, "node_output_volume");
5753  else if (compiler.output_type() == SHADER_TYPE_DISPLACEMENT)
5754  compiler.add(this, "node_output_displacement");
5755 }
5756 
5757 /* Map Range Node */
5758 
5760 {
5761  NodeType *type = NodeType::add("map_range", create, NodeType::SHADER);
5762 
5763  static NodeEnum type_enum;
5764  type_enum.insert("linear", NODE_MAP_RANGE_LINEAR);
5765  type_enum.insert("stepped", NODE_MAP_RANGE_STEPPED);
5766  type_enum.insert("smoothstep", NODE_MAP_RANGE_SMOOTHSTEP);
5767  type_enum.insert("smootherstep", NODE_MAP_RANGE_SMOOTHERSTEP);
5768  SOCKET_ENUM(range_type, "Type", type_enum, NODE_MAP_RANGE_LINEAR);
5769 
5770  SOCKET_IN_FLOAT(value, "Value", 1.0f);
5771  SOCKET_IN_FLOAT(from_min, "From Min", 0.0f);
5772  SOCKET_IN_FLOAT(from_max, "From Max", 1.0f);
5773  SOCKET_IN_FLOAT(to_min, "To Min", 0.0f);
5774  SOCKET_IN_FLOAT(to_max, "To Max", 1.0f);
5775  SOCKET_IN_FLOAT(steps, "Steps", 4.0f);
5776  SOCKET_IN_BOOLEAN(clamp, "Clamp", false);
5777 
5778  SOCKET_OUT_FLOAT(result, "Result");
5779 
5780  return type;
5781 }
5782 
5783 MapRangeNode::MapRangeNode() : ShaderNode(get_node_type())
5784 {
5785 }
5786 
5788 {
5789  if (clamp) {
5790  ShaderOutput *result_out = output("Result");
5791  if (!result_out->links.empty()) {
5792  ClampNode *clamp_node = graph->create_node<ClampNode>();
5793  clamp_node->set_clamp_type(NODE_CLAMP_RANGE);
5794  graph->add(clamp_node);
5795  graph->relink(result_out, clamp_node->output("Result"));
5796  graph->connect(result_out, clamp_node->input("Value"));
5797  if (input("To Min")->link) {
5798  graph->connect(input("To Min")->link, clamp_node->input("Min"));
5799  }
5800  else {
5801  clamp_node->set_min(to_min);
5802  }
5803  if (input("To Max")->link) {
5804  graph->connect(input("To Max")->link, clamp_node->input("Max"));
5805  }
5806  else {
5807  clamp_node->set_max(to_max);
5808  }
5809  }
5810  }
5811 }
5812 
5813 void MapRangeNode::compile(SVMCompiler &compiler)
5814 {
5815  ShaderInput *value_in = input("Value");
5816  ShaderInput *from_min_in = input("From Min");
5817  ShaderInput *from_max_in = input("From Max");
5818  ShaderInput *to_min_in = input("To Min");
5819  ShaderInput *to_max_in = input("To Max");
5820  ShaderInput *steps_in = input("Steps");
5821  ShaderOutput *result_out = output("Result");
5822 
5823  int value_stack_offset = compiler.stack_assign(value_in);
5824  int from_min_stack_offset = compiler.stack_assign_if_linked(from_min_in);
5825  int from_max_stack_offset = compiler.stack_assign_if_linked(from_max_in);
5826  int to_min_stack_offset = compiler.stack_assign_if_linked(to_min_in);
5827  int to_max_stack_offset = compiler.stack_assign_if_linked(to_max_in);
5828  int steps_stack_offset = compiler.stack_assign(steps_in);
5829  int result_stack_offset = compiler.stack_assign(result_out);
5830 
5831  compiler.add_node(
5833  value_stack_offset,
5834  compiler.encode_uchar4(
5835  from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset),
5836  compiler.encode_uchar4(range_type, steps_stack_offset, result_stack_offset));
5837 
5838  compiler.add_node(__float_as_int(from_min),
5839  __float_as_int(from_max),
5840  __float_as_int(to_min),
5841  __float_as_int(to_max));
5842  compiler.add_node(__float_as_int(steps));
5843 }
5844 
5845 void MapRangeNode::compile(OSLCompiler &compiler)
5846 {
5847  compiler.parameter(this, "range_type");
5848  compiler.add(this, "node_map_range");
5849 }
5850 
5851 /* Clamp Node */
5852 
5854 {
5855  NodeType *type = NodeType::add("clamp", create, NodeType::SHADER);
5856 
5857  static NodeEnum type_enum;
5858  type_enum.insert("minmax", NODE_CLAMP_MINMAX);
5859  type_enum.insert("range", NODE_CLAMP_RANGE);
5860  SOCKET_ENUM(clamp_type, "Type", type_enum, NODE_CLAMP_MINMAX);
5861 
5862  SOCKET_IN_FLOAT(value, "Value", 1.0f);
5863  SOCKET_IN_FLOAT(min, "Min", 0.0f);
5864  SOCKET_IN_FLOAT(max, "Max", 1.0f);
5865 
5866  SOCKET_OUT_FLOAT(result, "Result");
5867 
5868  return type;
5869 }
5870 
5871 ClampNode::ClampNode() : ShaderNode(get_node_type())
5872 {
5873 }
5874 
5876 {
5877  if (folder.all_inputs_constant()) {
5878  if (clamp_type == NODE_CLAMP_RANGE && (min > max)) {
5879  folder.make_constant(clamp(value, max, min));
5880  }
5881  else {
5882  folder.make_constant(clamp(value, min, max));
5883  }
5884  }
5885 }
5886 
5887 void ClampNode::compile(SVMCompiler &compiler)
5888 {
5889  ShaderInput *value_in = input("Value");
5890  ShaderInput *min_in = input("Min");
5891  ShaderInput *max_in = input("Max");
5892  ShaderOutput *result_out = output("Result");
5893 
5894  int value_stack_offset = compiler.stack_assign(value_in);
5895  int min_stack_offset = compiler.stack_assign(min_in);
5896  int max_stack_offset = compiler.stack_assign(max_in);
5897  int result_stack_offset = compiler.stack_assign(result_out);
5898 
5899  compiler.add_node(NODE_CLAMP,
5900  value_stack_offset,
5901  compiler.encode_uchar4(min_stack_offset, max_stack_offset, clamp_type),
5902  result_stack_offset);
5904 }
5905 
5906 void ClampNode::compile(OSLCompiler &compiler)
5907 {
5908  compiler.parameter(this, "clamp_type");
5909  compiler.add(this, "node_clamp");
5910 }
5911 
5912 /* AOV Output */
5913 
5915 {
5916  NodeType *type = NodeType::add("aov_output", create, NodeType::SHADER);
5917 
5918  SOCKET_IN_COLOR(color, "Color", zero_float3());
5919  SOCKET_IN_FLOAT(value, "Value", 0.0f);
5920 
5921  SOCKET_STRING(name, "AOV Name", ustring(""));
5922 
5923  return type;
5924 }
5925 
5926 OutputAOVNode::OutputAOVNode() : ShaderNode(get_node_type())
5927 {
5928  special_type = SHADER_SPECIAL_TYPE_OUTPUT_AOV;
5929  slot = -1;
5930 }
5931 
5933 {
5934  slot = scene->film->get_aov_offset(scene, name.string(), is_color);
5935  if (slot == -1) {
5936  slot = scene->film->get_aov_offset(scene, name.string(), is_color);
5937  }
5938 
5939  if (slot == -1 || is_color) {
5940  input("Value")->disconnect();
5941  }
5942  if (slot == -1 || !is_color) {
5943  input("Color")->disconnect();
5944  }
5945 }
5946 
5947 void OutputAOVNode::compile(SVMCompiler &compiler)
5948 {
5949  assert(slot >= 0);
5950 
5951  if (is_color) {
5952  compiler.add_node(NODE_AOV_COLOR, compiler.stack_assign(input("Color")), slot);
5953  }
5954  else {
5955  compiler.add_node(NODE_AOV_VALUE, compiler.stack_assign(input("Value")), slot);
5956  }
5957 }
5958 
5959 void OutputAOVNode::compile(OSLCompiler & /*compiler*/)
5960 {
5961  /* TODO */
5962 }
5963 
5964 /* Math */
5965 
5967 {
5968  NodeType *type = NodeType::add("math", create, NodeType::SHADER);
5969 
5970  static NodeEnum type_enum;
5971  type_enum.insert("add", NODE_MATH_ADD);
5972  type_enum.insert("subtract", NODE_MATH_SUBTRACT);
5973  type_enum.insert("multiply", NODE_MATH_MULTIPLY);
5974  type_enum.insert("divide", NODE_MATH_DIVIDE);
5975  type_enum.insert("multiply_add", NODE_MATH_MULTIPLY_ADD);
5976  type_enum.insert("sine", NODE_MATH_SINE);
5977  type_enum.insert("cosine", NODE_MATH_COSINE);
5978  type_enum.insert("tangent", NODE_MATH_TANGENT);
5979  type_enum.insert("sinh", NODE_MATH_SINH);
5980  type_enum.insert("cosh", NODE_MATH_COSH);
5981  type_enum.insert("tanh", NODE_MATH_TANH);
5982  type_enum.insert("arcsine", NODE_MATH_ARCSINE);
5983  type_enum.insert("arccosine", NODE_MATH_ARCCOSINE);
5984  type_enum.insert("arctangent", NODE_MATH_ARCTANGENT);
5985  type_enum.insert("power", NODE_MATH_POWER);
5986  type_enum.insert("logarithm", NODE_MATH_LOGARITHM);
5987  type_enum.insert("minimum", NODE_MATH_MINIMUM);
5988  type_enum.insert("maximum", NODE_MATH_MAXIMUM);
5989  type_enum.insert("round", NODE_MATH_ROUND);
5990  type_enum.insert("less_than", NODE_MATH_LESS_THAN);
5991  type_enum.insert("greater_than", NODE_MATH_GREATER_THAN);
5992  type_enum.insert("modulo", NODE_MATH_MODULO);
5993  type_enum.insert("absolute", NODE_MATH_ABSOLUTE);
5994  type_enum.insert("arctan2", NODE_MATH_ARCTAN2);
5995  type_enum.insert("floor", NODE_MATH_FLOOR);
5996  type_enum.insert("ceil", NODE_MATH_CEIL);
5997  type_enum.insert("fraction", NODE_MATH_FRACTION);
5998  type_enum.insert("trunc", NODE_MATH_TRUNC);
5999  type_enum.insert("snap", NODE_MATH_SNAP);
6000  type_enum.insert("wrap", NODE_MATH_WRAP);
6001  type_enum.insert("pingpong", NODE_MATH_PINGPONG);
6002  type_enum.insert("sqrt", NODE_MATH_SQRT);
6003  type_enum.insert("inversesqrt", NODE_MATH_INV_SQRT);
6004  type_enum.insert("sign", NODE_MATH_SIGN);
6005  type_enum.insert("exponent", NODE_MATH_EXPONENT);
6006  type_enum.insert("radians", NODE_MATH_RADIANS);
6007  type_enum.insert("degrees", NODE_MATH_DEGREES);
6008  type_enum.insert("smoothmin", NODE_MATH_SMOOTH_MIN);
6009  type_enum.insert("smoothmax", NODE_MATH_SMOOTH_MAX);
6010  type_enum.insert("compare", NODE_MATH_COMPARE);
6011  SOCKET_ENUM(math_type, "Type", type_enum, NODE_MATH_ADD);
6012 
6013  SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
6014 
6015  SOCKET_IN_FLOAT(value1, "Value1", 0.5f);
6016  SOCKET_IN_FLOAT(value2, "Value2", 0.5f);
6017  SOCKET_IN_FLOAT(value3, "Value3", 0.0f);
6018 
6019  SOCKET_OUT_FLOAT(value, "Value");
6020 
6021  return type;
6022 }
6023 
6024 MathNode::MathNode() : ShaderNode(get_node_type())
6025 {
6026 }
6027 
6029 {
6030  if (use_clamp) {
6031  ShaderOutput *result_out = output("Value");
6032  if (!result_out->links.empty()) {
6033  ClampNode *clamp_node = graph->create_node<ClampNode>();
6034  clamp_node->set_clamp_type(NODE_CLAMP_MINMAX);
6035  clamp_node->set_min(0.0f);
6036  clamp_node->set_max(1.0f);
6037  graph->add(clamp_node);
6038  graph->relink(result_out, clamp_node->output("Result"));
6039  graph->connect(result_out, clamp_node->input("Value"));
6040  }
6041  }
6042 }
6043 
6045 {
6046  if (folder.all_inputs_constant()) {
6047  folder.make_constant(svm_math(math_type, value1, value2, value3));
6048  }
6049  else {
6050  folder.fold_math(math_type);
6051  }
6052 }
6053 
6054 void MathNode::compile(SVMCompiler &compiler)
6055 {
6056  ShaderInput *value1_in = input("Value1");
6057  ShaderInput *value2_in = input("Value2");
6058  ShaderInput *value3_in = input("Value3");
6059  ShaderOutput *value_out = output("Value");
6060 
6061  int value1_stack_offset = compiler.stack_assign(value1_in);
6062  int value2_stack_offset = compiler.stack_assign(value2_in);
6063  int value3_stack_offset = compiler.stack_assign(value3_in);
6064  int value_stack_offset = compiler.stack_assign(value_out);
6065 
6066  compiler.add_node(
6067  NODE_MATH,
6068  math_type,
6069  compiler.encode_uchar4(value1_stack_offset, value2_stack_offset, value3_stack_offset),
6070  value_stack_offset);
6071 }
6072 
6073 void MathNode::compile(OSLCompiler &compiler)
6074 {
6075  compiler.parameter(this, "math_type");
6076  compiler.add(this, "node_math");
6077 }
6078 
6079 /* VectorMath */
6080 
6082 {
6083  NodeType *type = NodeType::add("vector_math", create, NodeType::SHADER);
6084 
6085  static NodeEnum type_enum;
6086  type_enum.insert("add", NODE_VECTOR_MATH_ADD);
6087  type_enum.insert("subtract", NODE_VECTOR_MATH_SUBTRACT);
6088  type_enum.insert("multiply", NODE_VECTOR_MATH_MULTIPLY);
6089  type_enum.insert("divide", NODE_VECTOR_MATH_DIVIDE);
6090 
6091  type_enum.insert("cross_product", NODE_VECTOR_MATH_CROSS_PRODUCT);
6092  type_enum.insert("project", NODE_VECTOR_MATH_PROJECT);
6093  type_enum.insert("reflect", NODE_VECTOR_MATH_REFLECT);
6094  type_enum.insert("refract", NODE_VECTOR_MATH_REFRACT);
6095  type_enum.insert("faceforward", NODE_VECTOR_MATH_FACEFORWARD);
6096 
6097  type_enum.insert("dot_product", NODE_VECTOR_MATH_DOT_PRODUCT);
6098 
6099  type_enum.insert("distance", NODE_VECTOR_MATH_DISTANCE);
6100  type_enum.insert("length", NODE_VECTOR_MATH_LENGTH);
6101  type_enum.insert("scale", NODE_VECTOR_MATH_SCALE);
6102  type_enum.insert("normalize", NODE_VECTOR_MATH_NORMALIZE);
6103 
6104  type_enum.insert("snap", NODE_VECTOR_MATH_SNAP);
6105  type_enum.insert("floor", NODE_VECTOR_MATH_FLOOR);
6106  type_enum.insert("ceil", NODE_VECTOR_MATH_CEIL);
6107  type_enum.insert("modulo", NODE_VECTOR_MATH_MODULO);
6108  type_enum.insert("wrap", NODE_VECTOR_MATH_WRAP);
6109  type_enum.insert("fraction", NODE_VECTOR_MATH_FRACTION);
6110  type_enum.insert("absolute", NODE_VECTOR_MATH_ABSOLUTE);
6111  type_enum.insert("minimum", NODE_VECTOR_MATH_MINIMUM);
6112  type_enum.insert("maximum", NODE_VECTOR_MATH_MAXIMUM);
6113 
6114  type_enum.insert("sine", NODE_VECTOR_MATH_SINE);
6115  type_enum.insert("cosine", NODE_VECTOR_MATH_COSINE);
6116  type_enum.insert("tangent", NODE_VECTOR_MATH_TANGENT);
6117  SOCKET_ENUM(math_type, "Type", type_enum, NODE_VECTOR_MATH_ADD);
6118 
6119  SOCKET_IN_VECTOR(vector1, "Vector1", zero_float3());
6120  SOCKET_IN_VECTOR(vector2, "Vector2", zero_float3());
6121  SOCKET_IN_VECTOR(vector3, "Vector3", zero_float3());
6122  SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
6123 
6124  SOCKET_OUT_FLOAT(value, "Value");
6125  SOCKET_OUT_VECTOR(vector, "Vector");
6126 
6127  return type;
6128 }
6129 
6130 VectorMathNode::VectorMathNode() : ShaderNode(get_node_type())
6131 {
6132 }
6133 
6135 {
6136  float value = 0.0f;
6138 
6139  if (folder.all_inputs_constant()) {
6140  svm_vector_math(&value, &vector, math_type, vector1, vector2, vector3, scale);
6141  if (folder.output == output("Value")) {
6142  folder.make_constant(value);
6143  }
6144  else if (folder.output == output("Vector")) {
6145  folder.make_constant(vector);
6146  }
6147  }
6148  else {
6149  folder.fold_vector_math(math_type);
6150  }
6151 }
6152 
6153 void VectorMathNode::compile(SVMCompiler &compiler)
6154 {
6155  ShaderInput *vector1_in = input("Vector1");
6156  ShaderInput *vector2_in = input("Vector2");
6157  ShaderInput *param1_in = input("Scale");
6158  ShaderOutput *value_out = output("Value");
6159  ShaderOutput *vector_out = output("Vector");
6160 
6161  int vector1_stack_offset = compiler.stack_assign(vector1_in);
6162  int vector2_stack_offset = compiler.stack_assign(vector2_in);
6163  int param1_stack_offset = compiler.stack_assign(param1_in);
6164  int value_stack_offset = compiler.stack_assign_if_linked(value_out);
6165  int vector_stack_offset = compiler.stack_assign_if_linked(vector_out);
6166 
6167  /* 3 Vector Operators */
6168  if (math_type == NODE_VECTOR_MATH_WRAP || math_type == NODE_VECTOR_MATH_FACEFORWARD) {
6169  ShaderInput *vector3_in = input("Vector3");
6170  int vector3_stack_offset = compiler.stack_assign(vector3_in);
6171  compiler.add_node(
6173  math_type,
6174  compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, param1_stack_offset),
6175  compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
6176  compiler.add_node(vector3_stack_offset);
6177  }
6178  else {
6179  compiler.add_node(
6181  math_type,
6182  compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, param1_stack_offset),
6183  compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
6184  }
6185 }
6186 
6187 void VectorMathNode::compile(OSLCompiler &compiler)
6188 {
6189  compiler.parameter(this, "math_type");
6190  compiler.add(this, "node_vector_math");
6191 }
6192 
6193 /* Vector Rotate */
6194 
6196 {
6197  NodeType *type = NodeType::add("vector_rotate", create, NodeType::SHADER);
6198 
6199  static NodeEnum type_enum;
6200  type_enum.insert("axis", NODE_VECTOR_ROTATE_TYPE_AXIS);
6201  type_enum.insert("x_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_X);
6202  type_enum.insert("y_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Y);
6203  type_enum.insert("z_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Z);
6204  type_enum.insert("euler_xyz", NODE_VECTOR_ROTATE_TYPE_EULER_XYZ);
6205  SOCKET_ENUM(rotate_type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS);
6206 
6207  SOCKET_BOOLEAN(invert, "Invert", false);
6208 
6209  SOCKET_IN_VECTOR(vector, "Vector", zero_float3());
6210  SOCKET_IN_POINT(rotation, "Rotation", zero_float3());
6211  SOCKET_IN_POINT(center, "Center", zero_float3());
6212  SOCKET_IN_VECTOR(axis, "Axis", make_float3(0.0f, 0.0f, 1.0f));
6213  SOCKET_IN_FLOAT(angle, "Angle", 0.0f);
6214  SOCKET_OUT_VECTOR(vector, "Vector");
6215 
6216  return type;
6217 }
6218 
6219 VectorRotateNode::VectorRotateNode() : ShaderNode(get_node_type())
6220 {
6221 }
6222 
6223 void VectorRotateNode::compile(SVMCompiler &compiler)
6224 {
6225  ShaderInput *vector_in = input("Vector");
6226  ShaderInput *rotation_in = input("Rotation");
6227  ShaderInput *center_in = input("Center");
6228  ShaderInput *axis_in = input("Axis");
6229  ShaderInput *angle_in = input("Angle");
6230  ShaderOutput *vector_out = output("Vector");
6231 
6232  compiler.add_node(NODE_VECTOR_ROTATE,
6233  compiler.encode_uchar4(rotate_type,
6234  compiler.stack_assign(vector_in),
6235  compiler.stack_assign(rotation_in),
6236  invert),
6237  compiler.encode_uchar4(compiler.stack_assign(center_in),
6238  compiler.stack_assign(axis_in),
6239  compiler.stack_assign(angle_in)),
6240  compiler.stack_assign(vector_out));
6241 }
6242 
6243 void VectorRotateNode::compile(OSLCompiler &compiler)
6244 {
6245  compiler.parameter(this, "rotate_type");
6246  compiler.parameter(this, "invert");
6247  compiler.add(this, "node_vector_rotate");
6248 }
6249 
6250 /* VectorTransform */
6251 
6253 {
6254  NodeType *type = NodeType::add("vector_transform", create, NodeType::SHADER);
6255 
6256  static NodeEnum type_enum;
6257  type_enum.insert("vector", NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
6258  type_enum.insert("point", NODE_VECTOR_TRANSFORM_TYPE_POINT);
6259  type_enum.insert("normal", NODE_VECTOR_TRANSFORM_TYPE_NORMAL);
6260  SOCKET_ENUM(transform_type, "Type", type_enum, NODE_VECTOR_TRANSFORM_TYPE_VECTOR);
6261 
6262  static NodeEnum space_enum;
6264  space_enum.insert("object", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT);
6265  space_enum.insert("camera", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA);
6266  SOCKET_ENUM(convert_from, "Convert From", space_enum, NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD);
6267  SOCKET_ENUM(convert_to, "Convert To", space_enum, NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT);
6268 
6269  SOCKET_IN_VECTOR(vector, "Vector", zero_float3());
6270  SOCKET_OUT_VECTOR(vector, "Vector");
6271 
6272  return type;
6273 }
6274 
6275 VectorTransformNode::VectorTransformNode() : ShaderNode(get_node_type())
6276 {
6277 }
6278 
6280 {
6281  ShaderInput *vector_in = input("Vector");
6282  ShaderOutput *vector_out = output("Vector");
6283 
6284  compiler.add_node(
6286  compiler.encode_uchar4(transform_type, convert_from, convert_to),
6287  compiler.encode_uchar4(compiler.stack_assign(vector_in), compiler.stack_assign(vector_out)));
6288 }
6289 
6291 {
6292  compiler.parameter(this, "transform_type");
6293  compiler.parameter(this, "convert_from");
6294  compiler.parameter(this, "convert_to");
6295  compiler.add(this, "node_vector_transform");
6296 }
6297 
6298 /* BumpNode */
6299 
6301 {
6302  NodeType *type = NodeType::add("bump", create, NodeType::SHADER);
6303 
6304  SOCKET_BOOLEAN(invert, "Invert", false);
6305  SOCKET_BOOLEAN(use_object_space, "UseObjectSpace", false);
6306 
6307  /* this input is used by the user, but after graph transform it is no longer
6308  * used and moved to sampler center/x/y instead */
6309  SOCKET_IN_FLOAT(height, "Height", 1.0f);
6310 
6311  SOCKET_IN_FLOAT(sample_center, "SampleCenter", 0.0f);
6312  SOCKET_IN_FLOAT(sample_x, "SampleX", 0.0f);
6313  SOCKET_IN_FLOAT(sample_y, "SampleY", 0.0f);
6315  SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
6316  SOCKET_IN_FLOAT(distance, "Distance", 0.1f);
6317 
6318  SOCKET_OUT_NORMAL(normal, "Normal");
6319 
6320  return type;
6321 }
6322 
6323 BumpNode::BumpNode() : ShaderNode(get_node_type())
6324 {
6325  special_type = SHADER_SPECIAL_TYPE_BUMP;
6326 }
6327 
6328 void BumpNode::compile(SVMCompiler &compiler)
6329 {
6330  ShaderInput *center_in = input("SampleCenter");
6331  ShaderInput *dx_in = input("SampleX");
6332  ShaderInput *dy_in = input("SampleY");
6333  ShaderInput *normal_in = input("Normal");
6334  ShaderInput *strength_in = input("Strength");
6335  ShaderInput *distance_in = input("Distance");
6336  ShaderOutput *normal_out = output("Normal");
6337 
6338  /* pack all parameters in the node */
6339  compiler.add_node(NODE_SET_BUMP,
6340  compiler.encode_uchar4(compiler.stack_assign_if_linked(normal_in),
6341  compiler.stack_assign(distance_in),
6342  invert,
6343  use_object_space),
6344  compiler.encode_uchar4(compiler.stack_assign(center_in),
6345  compiler.stack_assign(dx_in),
6346  compiler.stack_assign(dy_in),
6347  compiler.stack_assign(strength_in)),
6348  compiler.stack_assign(normal_out));
6349 }
6350 
6351 void BumpNode::compile(OSLCompiler &compiler)
6352 {
6353  compiler.parameter(this, "invert");
6354  compiler.parameter(this, "use_object_space");
6355  compiler.add(this, "node_bump");
6356 }
6357 
6359 {
6360  ShaderInput *height_in = input("Height");
6361  ShaderInput *normal_in = input("Normal");
6362 
6363  if (height_in->link == NULL) {
6364  if (normal_in->link == NULL) {
6365  GeometryNode *geom = folder.graph->create_node<GeometryNode>();
6366  folder.graph->add(geom);
6367  folder.bypass(geom->output("Normal"));
6368  }
6369  else {
6370  folder.bypass(normal_in->link);
6371  }
6372  }
6373 
6374  /* TODO(sergey): Ignore bump with zero strength. */
6375 }
6376 
6377 /* Curve node */
6378 
6379 CurvesNode::CurvesNode(const NodeType *node_type) : ShaderNode(node_type)
6380 {
6381 }
6382 
6384 {
6385  ShaderInput *fac_in = input("Fac");
6386 
6387  /* evaluate fully constant node */
6388  if (folder.all_inputs_constant()) {
6389  if (curves.size() == 0) {
6390  return;
6391  }
6392 
6393  float3 pos = (value - make_float3(min_x, min_x, min_x)) / (max_x - min_x);
6394  float3 result;
6395 
6396  result[0] = rgb_ramp_lookup(curves.data(), pos[0], true, true, curves.size()).x;
6397  result[1] = rgb_ramp_lookup(curves.data(), pos[1], true, true, curves.size()).y;
6398  result[2] = rgb_ramp_lookup(curves.data(), pos[2], true, true, curves.size()).z;
6399 
6400  folder.make_constant(interp(value, result, fac));
6401  }
6402  /* remove no-op node */
6403  else if (!fac_in->link && fac == 0.0f) {
6404  /* link is not null because otherwise all inputs are constant */
6405  folder.bypass(value_in->link);
6406  }
6407 }
6408 
6410  int type,
6411  ShaderInput *value_in,
6412  ShaderOutput *value_out)
6413 {
6414  if (curves.size() == 0)
6415  return;
6416 
6417  ShaderInput *fac_in = input("Fac");
6418 
6419  compiler.add_node(type,
6420  compiler.encode_uchar4(compiler.stack_assign(fac_in),
6421  compiler.stack_assign(value_in),
6422  compiler.stack_assign(value_out)),
6423  __float_as_int(min_x),
6424  __float_as_int(max_x));
6425 
6426  compiler.add_node(curves.size());
6427  for (int i = 0; i < curves.size(); i++)
6428  compiler.add_node(float3_to_float4(curves[i]));
6429 }
6430 
6431 void CurvesNode::compile(OSLCompiler &compiler, const char *name)
6432 {
6433  if (curves.size() == 0)
6434  return;
6435 
6436  compiler.parameter_color_array("ramp", curves);
6437  compiler.parameter(this, "min_x");
6438  compiler.parameter(this, "max_x");
6439  compiler.add(this, name);
6440 }
6441 
6442 void CurvesNode::compile(SVMCompiler & /*compiler*/)
6443 {
6444  assert(0);
6445 }
6446 
6447 void CurvesNode::compile(OSLCompiler & /*compiler*/)
6448 {
6449  assert(0);
6450 }
6451 
6452 /* RGBCurvesNode */
6453 
6455 {
6456  NodeType *type = NodeType::add("rgb_curves", create, NodeType::SHADER);
6457 
6458  SOCKET_COLOR_ARRAY(curves, "Curves", array<float3>());
6459  SOCKET_FLOAT(min_x, "Min X", 0.0f);
6460  SOCKET_FLOAT(max_x, "Max X", 1.0f);
6461 
6462  SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
6463  SOCKET_IN_COLOR(value, "Color", zero_float3());
6464 
6465  SOCKET_OUT_COLOR(value, "Color");
6466 
6467  return type;
6468 }
6469 
6470 RGBCurvesNode::RGBCurvesNode() : CurvesNode(get_node_type())
6471 {
6472 }
6473 
6475 {
6476  CurvesNode::constant_fold(folder, input("Color"));
6477 }
6478 
6479 void RGBCurvesNode::compile(SVMCompiler &compiler)
6480 {
6481  CurvesNode::compile(compiler, NODE_RGB_CURVES, input("Color"), output("Color"));
6482 }
6483 
6484 void RGBCurvesNode::compile(OSLCompiler &compiler)
6485 {
6486  CurvesNode::compile(compiler, "node_rgb_curves");
6487 }
6488 
6489 /* VectorCurvesNode */
6490 
6492 {
6493  NodeType *type = NodeType::add("vector_curves", create, NodeType::SHADER);
6494 
6495  SOCKET_VECTOR_ARRAY(curves, "Curves", array<float3>());
6496  SOCKET_FLOAT(min_x, "Min X", 0.0f);
6497  SOCKET_FLOAT(max_x, "Max X", 1.0f);
6498 
6499  SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
6500  SOCKET_IN_VECTOR(value, "Vector", zero_float3());
6501 
6502  SOCKET_OUT_VECTOR(value, "Vector");
6503 
6504  return type;
6505 }
6506 
6507 VectorCurvesNode::VectorCurvesNode() : CurvesNode(get_node_type())
6508 {
6509 }
6510 
6512 {
6513  CurvesNode::constant_fold(folder, input("Vector"));
6514 }
6515 
6516 void VectorCurvesNode::compile(SVMCompiler &compiler)
6517 {
6518  CurvesNode::compile(compiler, NODE_VECTOR_CURVES, input("Vector"), output("Vector"));
6519 }
6520 
6521 void VectorCurvesNode::compile(OSLCompiler &compiler)
6522 {
6523  CurvesNode::compile(compiler, "node_vector_curves");
6524 }
6525 
6526 /* RGBRampNode */
6527 
6529 {
6530  NodeType *type = NodeType::add("rgb_ramp", create, NodeType::SHADER);
6531 
6532  SOCKET_COLOR_ARRAY(ramp, "Ramp", array<float3>());
6533  SOCKET_FLOAT_ARRAY(ramp_alpha, "Ramp Alpha", array<float>());
6534  SOCKET_BOOLEAN(interpolate, "Interpolate", true);
6535 
6536  SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
6537 
6538  SOCKET_OUT_COLOR(color, "Color");
6539  SOCKET_OUT_FLOAT(alpha, "Alpha");
6540 
6541  return type;
6542 }
6543 
6544 RGBRampNode::RGBRampNode() : ShaderNode(get_node_type())
6545 {
6546 }
6547 
6549 {
6550  if (ramp.size() == 0 || ramp.size() != ramp_alpha.size())
6551  return;
6552 
6553  if (folder.all_inputs_constant()) {
6554  float f = clamp(fac, 0.0f, 1.0f) * (ramp.size() - 1);
6555 
6556  /* clamp int as well in case of NaN */
6557  int i = clamp((int)f, 0, ramp.size() - 1);
6558  float t = f - (float)i;
6559 
6560  bool use_lerp = interpolate && t > 0.0f;
6561 
6562  if (folder.output == output("Color")) {
6563  float3 color = rgb_ramp_lookup(ramp.data(), fac, use_lerp, false, ramp.size());
6564  folder.make_constant(color);
6565  }
6566  else if (folder.output == output("Alpha")) {
6567  float alpha = float_ramp_lookup(ramp_alpha.data(), fac, use_lerp, false, ramp_alpha.size());
6568  folder.make_constant(alpha);
6569  }
6570  }
6571 }
6572 
6573 void RGBRampNode::compile(SVMCompiler &compiler)
6574 {
6575  if (ramp.size() == 0 || ramp.size() != ramp_alpha.size())
6576  return;
6577 
6578  ShaderInput *fac_in = input("Fac");
6579  ShaderOutput *color_out = output("Color");
6580  ShaderOutput *alpha_out = output("Alpha");
6581 
6582  compiler.add_node(NODE_RGB_RAMP,
6583  compiler.encode_uchar4(compiler.stack_assign(fac_in),
6584  compiler.stack_assign_if_linked(color_out),
6585  compiler.stack_assign_if_linked(alpha_out)),
6586  interpolate);
6587 
6588  compiler.add_node(ramp.size());
6589  for (int i = 0; i < ramp.size(); i++)
6590  compiler.add_node(make_float4(ramp[i].x, ramp[i].y, ramp[i].z, ramp_alpha[i]));
6591 }
6592 
6593 void RGBRampNode::compile(OSLCompiler &compiler)
6594 {
6595  if (ramp.size() == 0 || ramp.size() != ramp_alpha.size())
6596  return;
6597 
6598  compiler.parameter_color_array("ramp_color", ramp);
6599  compiler.parameter_array("ramp_alpha", ramp_alpha.data(), ramp_alpha.size());
6600  compiler.parameter(this, "interpolate");
6601 
6602  compiler.add(this, "node_rgb_ramp");
6603 }
6604 
6605 /* Set Normal Node */
6606 
6608 {
6609  NodeType *type = NodeType::add("set_normal", create, NodeType::SHADER);
6610 
6611  SOCKET_IN_VECTOR(direction, "Direction", zero_float3());
6612  SOCKET_OUT_NORMAL(normal, "Normal");
6613 
6614  return type;
6615 }
6616 
6617 SetNormalNode::SetNormalNode() : ShaderNode(get_node_type())
6618 {
6619 }
6620 
6621 void SetNormalNode::compile(SVMCompiler &compiler)
6622 {
6623  ShaderInput *direction_in = input("Direction");
6624  ShaderOutput *normal_out = output("Normal");
6625 
6627  compiler.stack_assign(direction_in),
6628  compiler.stack_assign(normal_out));
6629 }
6630 
6631 void SetNormalNode::compile(OSLCompiler &compiler)
6632 {
6633  compiler.add(this, "node_set_normal");
6634 }
6635 
6636 /* OSLNode */
6637 
6638 OSLNode::OSLNode() : ShaderNode(new NodeType(NodeType::SHADER))
6639 {
6640  special_type = SHADER_SPECIAL_TYPE_OSL;
6641 }
6642 
6644 {
6645  delete type;
6646 }
6647 
6649 {
6650  return OSLNode::create(graph, this->inputs.size(), this);
6651 }
6652 
6653 OSLNode *OSLNode::create(ShaderGraph *graph, size_t num_inputs, const OSLNode *from)
6654 {
6655  /* allocate space for the node itself and parameters, aligned to 16 bytes
6656  * assuming that's the most parameter types need */
6657  size_t node_size = align_up(sizeof(OSLNode), 16);
6658  size_t inputs_size = align_up(SocketType::max_size(), 16) * num_inputs;
6659 
6660  char *node_memory = (char *)operator new(node_size + inputs_size);
6661  memset(node_memory, 0, node_size + inputs_size);
6662 
6663  if (!from) {
6664  OSLNode *node = new (node_memory) OSLNode();
6665  node->set_owner(graph);
6666  return node;
6667  }
6668  else {
6669  /* copy input default values and node type for cloning */
6670  memcpy(node_memory + node_size, (char *)from + node_size, inputs_size);
6671 
6672  OSLNode *node = new (node_memory) OSLNode(*from);
6673  node->type = new NodeType(*(from->type));
6674  node->set_owner(from->owner);
6675  return node;
6676  }
6677 }
6678 
6680 {
6681  /* pointer to default value storage, which is the same as our actual value */
6682  size_t num_inputs = type->inputs.size();
6683  size_t inputs_size = align_up(SocketType::max_size(), 16) * num_inputs;
6684  return (char *)this + align_up(sizeof(OSLNode), 16) + inputs_size;
6685 }
6686 
6687 void OSLNode::add_input(ustring name, SocketType::Type socket_type)
6688 {
6689  char *memory = input_default_value();
6690  size_t offset = memory - (char *)this;
6691  const_cast<NodeType *>(type)->register_input(
6692  name, name, socket_type, offset, memory, NULL, NULL, SocketType::LINKABLE);
6693 }
6694 
6695 void OSLNode::add_output(ustring name, SocketType::Type socket_type)
6696 {
6697  const_cast<NodeType *>(type)->register_output(name, name, socket_type);
6698 }
6699 
6701 {
6702  /* doesn't work for SVM, obviously ... */
6703 }
6704 
6705 void OSLNode::compile(OSLCompiler &compiler)
6706 {
6707  if (!filepath.empty())
6708  compiler.add(this, filepath.c_str(), true);
6709  else
6710  compiler.add(this, bytecode_hash.c_str(), false);
6711 }
6712 
6713 /* Normal Map */
6714 
6716 {
6717  NodeType *type = NodeType::add("normal_map", create, NodeType::SHADER);
6718 
6719  static NodeEnum space_enum;
6720  space_enum.insert("tangent", NODE_NORMAL_MAP_TANGENT);
6721  space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
6722  space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
6723  space_enum.insert("blender_object", NODE_NORMAL_MAP_BLENDER_OBJECT);
6724  space_enum.insert("blender_world", NODE_NORMAL_MAP_BLENDER_WORLD);
6725  SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT);
6726 
6727  SOCKET_STRING(attribute, "Attribute", ustring());
6728 
6730  normal_osl, "NormalIn", zero_float3(), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
6731  SOCKET_IN_FLOAT(strength, "Strength", 1.0f);
6732  SOCKET_IN_COLOR(color, "Color", make_float3(0.5f, 0.5f, 1.0f));
6733 
6734  SOCKET_OUT_NORMAL(normal, "Normal");
6735 
6736  return type;
6737 }
6738 
6739 NormalMapNode::NormalMapNode() : ShaderNode(get_node_type())
6740 {
6741 }
6742 
6744 {
6745  if (shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) {
6746  if (attribute.empty()) {
6749  }
6750  else {
6751  attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
6752  attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
6753  }
6754 
6756  }
6757 
6759 }
6760 
6761 void NormalMapNode::compile(SVMCompiler &compiler)
6762 {
6763  ShaderInput *color_in = input("Color");
6764  ShaderInput *strength_in = input("Strength");
6765  ShaderOutput *normal_out = output("Normal");
6766  int attr = 0, attr_sign = 0;
6767 
6768  if (space == NODE_NORMAL_MAP_TANGENT) {
6769  if (attribute.empty()) {
6770  attr = compiler.attribute(ATTR_STD_UV_TANGENT);
6771  attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN);
6772  }
6773  else {
6774  attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
6775  attr_sign = compiler.attribute(
6776  ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
6777  }
6778  }
6779 
6780  compiler.add_node(NODE_NORMAL_MAP,
6781  compiler.encode_uchar4(compiler.stack_assign(color_in),
6782  compiler.stack_assign(strength_in),
6783  compiler.stack_assign(normal_out),
6784  space),
6785  attr,
6786  attr_sign);
6787 }
6788 
6789 void NormalMapNode::compile(OSLCompiler &compiler)
6790 {
6791  if (space == NODE_NORMAL_MAP_TANGENT) {
6792  if (attribute.empty()) {
6793  compiler.parameter("attr_name", ustring("geom:tangent"));
6794  compiler.parameter("attr_sign_name", ustring("geom:tangent_sign"));
6795  }
6796  else {
6797  compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
6798  compiler.parameter("attr_sign_name",
6799  ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
6800  }
6801  }
6802 
6803  compiler.parameter(this, "space");
6804  compiler.add(this, "node_normal_map");
6805 }
6806 
6807 /* Tangent */
6808 
6810 {
6811  NodeType *type = NodeType::add("tangent", create, NodeType::SHADER);
6812 
6813  static NodeEnum direction_type_enum;
6814  direction_type_enum.insert("radial", NODE_TANGENT_RADIAL);
6815  direction_type_enum.insert("uv_map", NODE_TANGENT_UVMAP);
6816  SOCKET_ENUM(direction_type, "Direction Type", direction_type_enum, NODE_TANGENT_RADIAL);
6817 
6818  static NodeEnum axis_enum;
6819  axis_enum.insert("x", NODE_TANGENT_AXIS_X);
6820  axis_enum.insert("y", NODE_TANGENT_AXIS_Y);
6821  axis_enum.insert("z", NODE_TANGENT_AXIS_Z);
6822  SOCKET_ENUM(axis, "Axis", axis_enum, NODE_TANGENT_AXIS_X);
6823 
6824  SOCKET_STRING(attribute, "Attribute", ustring());
6825 
6827  normal_osl, "NormalIn", zero_float3(), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL);
6828  SOCKET_OUT_NORMAL(tangent, "Tangent");
6829 
6830  return type;
6831 }
6832 
6833 TangentNode::TangentNode() : ShaderNode(get_node_type())
6834 {
6835 }
6836 
6838 {
6839  if (shader->has_surface) {
6840  if (direction_type == NODE_TANGENT_UVMAP) {
6841  if (attribute.empty())
6843  else
6844  attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
6845  }
6846  else
6848  }
6849 
6851 }
6852 
6853 void TangentNode::compile(SVMCompiler &compiler)
6854 {
6855  ShaderOutput *tangent_out = output("Tangent");
6856  int attr;
6857 
6858  if (direction_type == NODE_TANGENT_UVMAP) {
6859  if (attribute.empty())
6860  attr = compiler.attribute(ATTR_STD_UV_TANGENT);
6861  else
6862  attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
6863  }
6864  else
6865  attr = compiler.attribute(ATTR_STD_GENERATED);
6866 
6867  compiler.add_node(
6868  NODE_TANGENT,
6869  compiler.encode_uchar4(compiler.stack_assign(tangent_out), direction_type, axis),
6870  attr);
6871 }
6872 
6873 void TangentNode::compile(OSLCompiler &compiler)
6874 {
6875  if (direction_type == NODE_TANGENT_UVMAP) {
6876  if (attribute.empty())
6877  compiler.parameter("attr_name", ustring("geom:tangent"));
6878  else
6879  compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
6880  }
6881 
6882  compiler.parameter(this, "direction_type");
6883  compiler.parameter(this, "axis");
6884  compiler.add(this, "node_tangent");
6885 }
6886 
6887 /* Bevel */
6888 
6890 {
6891  NodeType *type = NodeType::add("bevel", create, NodeType::SHADER);
6892 
6893  SOCKET_INT(samples, "Samples", 4);
6894 
6895  SOCKET_IN_FLOAT(radius, "Radius", 0.05f);
6897 
6898  SOCKET_OUT_NORMAL(bevel, "Normal");
6899 
6900  return type;
6901 }
6902 
6903 BevelNode::BevelNode() : ShaderNode(get_node_type())
6904 {
6905 }
6906 
6907 void BevelNode::compile(SVMCompiler &compiler)
6908 {
6909  ShaderInput *radius_in = input("Radius");
6910  ShaderInput *normal_in = input("Normal");
6911  ShaderOutput *normal_out = output("Normal");
6912 
6913  compiler.add_node(NODE_BEVEL,
6914  compiler.encode_uchar4(samples,
6915  compiler.stack_assign(radius_in),
6916  compiler.stack_assign_if_linked(normal_in),
6917  compiler.stack_assign(normal_out)));
6918 }
6919 
6920 void BevelNode::compile(OSLCompiler &compiler)
6921 {
6922  compiler.parameter(this, "samples");
6923  compiler.add(this, "node_bevel");
6924 }
6925 
6926 /* Displacement */
6927 
6929 {
6930  NodeType *type = NodeType::add("displacement", create, NodeType::SHADER);
6931 
6932  static NodeEnum space_enum;
6933  space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
6934  space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
6935 
6936  SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_OBJECT);
6937 
6938  SOCKET_IN_FLOAT(height, "Height", 0.0f);
6939  SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.5f);
6940  SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
6942 
6943  SOCKET_OUT_VECTOR(displacement, "Displacement");
6944 
6945  return type;
6946 }
6947 
6948 DisplacementNode::DisplacementNode() : ShaderNode(get_node_type())
6949 {
6950 }
6951 
6953 {
6954  if (folder.all_inputs_constant()) {
6955  if ((height - midlevel == 0.0f) || (scale == 0.0f)) {
6956  folder.make_zero();
6957  }
6958  }
6959 }
6960 
6961 void DisplacementNode::compile(SVMCompiler &compiler)
6962 {
6963  ShaderInput *height_in = input("Height");
6964  ShaderInput *midlevel_in = input("Midlevel");
6965  ShaderInput *scale_in = input("Scale");
6966  ShaderInput *normal_in = input("Normal");
6967  ShaderOutput *displacement_out = output("Displacement");
6968 
6969  compiler.add_node(NODE_DISPLACEMENT,
6970  compiler.encode_uchar4(compiler.stack_assign(height_in),
6971  compiler.stack_assign(midlevel_in),
6972  compiler.stack_assign(scale_in),
6973  compiler.stack_assign_if_linked(normal_in)),
6974  compiler.stack_assign(displacement_out),
6975  space);
6976 }
6977 
6978 void DisplacementNode::compile(OSLCompiler &compiler)
6979 {
6980  compiler.parameter(this, "space");
6981  compiler.add(this, "node_displacement");
6982 }
6983 
6984 /* Vector Displacement */
6985 
6987 {
6988  NodeType *type = NodeType::add("vector_displacement", create, NodeType::SHADER);
6989 
6990  static NodeEnum space_enum;
6991  space_enum.insert("tangent", NODE_NORMAL_MAP_TANGENT);
6992  space_enum.insert("object", NODE_NORMAL_MAP_OBJECT);
6993  space_enum.insert("world", NODE_NORMAL_MAP_WORLD);
6994 
6995  SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT);
6996  SOCKET_STRING(attribute, "Attribute", ustring());
6997 
6998  SOCKET_IN_COLOR(vector, "Vector", zero_float3());
6999  SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.0f);
7000  SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
7001 
7002  SOCKET_OUT_VECTOR(displacement, "Displacement");
7003 
7004  return type;
7005 }
7006 
7007 VectorDisplacementNode::VectorDisplacementNode() : ShaderNode(get_node_type())
7008 {
7009 }
7010 
7012 {
7013  if (folder.all_inputs_constant()) {
7014  if ((vector == zero_float3() && midlevel == 0.0f) || (scale == 0.0f)) {
7015  folder.make_zero();
7016  }
7017  }
7018 }
7019 
7021 {
7022  if (shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) {
7023  if (attribute.empty()) {
7026  }
7027  else {
7028  attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str()));
7029  attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
7030  }
7031 
7033  }
7034 
7036 }
7037 
7039 {
7040  ShaderInput *vector_in = input("Vector");
7041  ShaderInput *midlevel_in = input("Midlevel");
7042  ShaderInput *scale_in = input("Scale");
7043  ShaderOutput *displacement_out = output("Displacement");
7044  int attr = 0, attr_sign = 0;
7045 
7046  if (space == NODE_NORMAL_MAP_TANGENT) {
7047  if (attribute.empty()) {
7048  attr = compiler.attribute(ATTR_STD_UV_TANGENT);
7049  attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN);
7050  }
7051  else {
7052  attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str()));
7053  attr_sign = compiler.attribute(
7054  ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
7055  }
7056  }
7057 
7059  compiler.encode_uchar4(compiler.stack_assign(vector_in),
7060  compiler.stack_assign(midlevel_in),
7061  compiler.stack_assign(scale_in),
7062  compiler.stack_assign(displacement_out)),
7063  attr,
7064  attr_sign);
7065 
7066  compiler.add_node(space);
7067 }
7068 
7070 {
7071  if (space == NODE_NORMAL_MAP_TANGENT) {
7072  if (attribute.empty()) {
7073  compiler.parameter("attr_name", ustring("geom:tangent"));
7074  compiler.parameter("attr_sign_name", ustring("geom:tangent_sign"));
7075  }
7076  else {
7077  compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
7078  compiler.parameter("attr_sign_name",
7079  ustring((string(attribute.c_str()) + ".tangent_sign").c_str()));
7080  }
7081  }
7082 
7083  compiler.parameter(this, "space");
7084  compiler.add(this, "node_vector_displacement");
7085 }
7086 
typedef float(TangentPoint)[2]
KDTree *BLI_kdtree_nd_() new(unsigned int maxsize)
Definition: kdtree_impl.h:99
MINLINE float signf(float f)
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
Definition: math_color.c:229
void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b)
Definition: math_color.c:31
unsigned int uint
Definition: BLI_sys_types.h:83
static uint8 component(Color32 c, uint i)
Definition: ColorBlock.cpp:126
@ NODE_VECTOR_MATH_NORMALIZE
@ NODE_VECTOR_MATH_LENGTH
@ NODE_VECTOR_MATH_CROSS_PRODUCT
@ NODE_VECTOR_MATH_CEIL
@ NODE_VECTOR_MATH_MODULO
@ NODE_VECTOR_MATH_ADD
@ NODE_VECTOR_MATH_COSINE
@ NODE_VECTOR_MATH_REFLECT
@ NODE_VECTOR_MATH_WRAP
@ NODE_VECTOR_MATH_REFRACT
@ NODE_VECTOR_MATH_DOT_PRODUCT
@ NODE_VECTOR_MATH_ABSOLUTE
@ NODE_VECTOR_MATH_DIVIDE
@ NODE_VECTOR_MATH_TANGENT
@ NODE_VECTOR_MATH_DISTANCE
@ NODE_VECTOR_MATH_FLOOR
@ NODE_VECTOR_MATH_SNAP
@ NODE_VECTOR_MATH_SINE
@ NODE_VECTOR_MATH_FRACTION
@ NODE_VECTOR_MATH_PROJECT
@ NODE_VECTOR_MATH_MULTIPLY
@ NODE_VECTOR_MATH_SCALE
@ NODE_VECTOR_MATH_MAXIMUM
@ NODE_VECTOR_MATH_FACEFORWARD
@ NODE_VECTOR_MATH_SUBTRACT
@ NODE_VECTOR_MATH_MINIMUM
@ NODE_MATH_SINH
@ NODE_MATH_SMOOTH_MIN
@ NODE_MATH_TRUNC
@ NODE_MATH_COSH
@ NODE_MATH_SIGN
@ NODE_MATH_DEGREES
@ NODE_MATH_MODULO
@ NODE_MATH_ABSOLUTE
@ NODE_MATH_DIVIDE
@ NODE_MATH_SINE
@ NODE_MATH_ARCTAN2
@ NODE_MATH_ARCCOSINE
@ NODE_MATH_MULTIPLY_ADD
@ NODE_MATH_POWER
@ NODE_MATH_WRAP
@ NODE_MATH_ARCTANGENT
@ NODE_MATH_MINIMUM
@ NODE_MATH_SQRT
@ NODE_MATH_CEIL
@ NODE_MATH_TANH
@ NODE_MATH_GREATER_THAN
@ NODE_MATH_ADD
@ NODE_MATH_FRACTION
@ NODE_MATH_EXPONENT
@ NODE_MATH_LESS_THAN
@ NODE_MATH_ARCSINE
@ NODE_MATH_MAXIMUM
@ NODE_MATH_LOGARITHM
@ NODE_MATH_COMPARE
@ NODE_MATH_INV_SQRT
@ NODE_MATH_MULTIPLY
@ NODE_MATH_PINGPONG
@ NODE_MATH_ROUND
@ NODE_MATH_FLOOR
@ NODE_MATH_SUBTRACT
@ NODE_MATH_COSINE
@ NODE_MATH_SNAP
@ NODE_MATH_TANGENT
@ NODE_MATH_SMOOTH_MAX
@ NODE_MATH_RADIANS
@ NODE_MAPPING_TYPE_POINT
@ NODE_MAPPING_TYPE_VECTOR
@ NODE_MAPPING_TYPE_TEXTURE
@ NODE_MAPPING_TYPE_NORMAL
@ NODE_VECTOR_ROTATE_TYPE_AXIS
@ NODE_VECTOR_ROTATE_TYPE_AXIS_Z
@ NODE_VECTOR_ROTATE_TYPE_AXIS_X
@ NODE_VECTOR_ROTATE_TYPE_EULER_XYZ
@ NODE_VECTOR_ROTATE_TYPE_AXIS_Y
@ NODE_CLAMP_RANGE
@ NODE_CLAMP_MINMAX
@ NODE_MAP_RANGE_STEPPED
@ NODE_MAP_RANGE_SMOOTHERSTEP
@ NODE_MAP_RANGE_SMOOTHSTEP
@ NODE_MAP_RANGE_LINEAR
NSNotificationCenter * center
_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 GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_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 GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_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
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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 y
_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 GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse BSDF
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:4710
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:2320
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:5408
static AttributeStandard name_standard(const char *name)
Definition: attribute.cpp:373
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:3182
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:5696
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:5160
virtual bool has_bump()
Definition: nodes.cpp:2230
ClosureType closure
Definition: nodes.h:550
BsdfBaseNode(const NodeType *node_type)
Definition: nodes.cpp:2225
BsdfNode(const NodeType *node_type)
Definition: nodes.cpp:2240
void compile(SVMCompiler &compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3=NULL, ShaderInput *param4=NULL)
Definition: nodes.cpp:2244
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:6358
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:5875
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:4660
static bool colorspace_is_data(ustring colorspace)
Definition: colorspace.cpp:85
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:5061
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:4965
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:5013
void make_one() const
void make_constant_clamp(float value, bool clamp) const
void discard() const
void bypass(ShaderOutput *output) const
void bypass_or_discard(ShaderInput *input) const
void fold_mapping(NodeMappingType type) const
ShaderGraph *const graph
Definition: constant_fold.h:33
bool all_inputs_constant() const
bool try_bypass_or_make_constant(ShaderInput *input, bool clamp=false) const
void make_zero() const
bool is_zero(ShaderInput *input) const
bool is_one(ShaderInput *input) const
void fold_math(NodeMathType type) const
void make_constant(float value) const
ShaderOutput *const output
Definition: constant_fold.h:35
void fold_mix(NodeMix type, bool clamp) const
void fold_vector_math(NodeVectorMathType type) const
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:2094
float value_float
Definition: nodes.h:513
float3 value_vector
Definition: nodes.h:516
ConvertNode(SocketType::Type from, SocketType::Type to, bool autoconvert=false)
Definition: nodes.cpp:2072
float3 value_color
Definition: nodes.h:515
CurvesNode(const NodeType *node_type)
Definition: nodes.cpp:6379
virtual void constant_fold(const ConstantFolder &)
Definition: graph.h:174
void compile(SVMCompiler &compiler, int type, ShaderInput *value_in, ShaderOutput *value_out)
Definition: nodes.cpp:6409
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:6952
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:3133
ImageParams image_params() const
Definition: nodes.cpp:541
ShaderNode * clone(ShaderGraph *graph) const
Definition: nodes.cpp:534
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:552
int get_aov_offset(Scene *scene, string name, bool &is_color)
Definition: film.cpp:708
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:5104
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:3685
int get_group()
Definition: nodes.cpp:3789
virtual void get_uv_tiles(ustring map, unordered_set< int > &tiles)=0
void simplify_settings(Scene *scene)
Definition: nodes.cpp:2472
bool has_integrator_dependency()
Definition: nodes.cpp:2509
bool has_integrator_dependency()
Definition: nodes.cpp:2416
void simplify_settings(Scene *scene)
Definition: nodes.cpp:2379
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:4389
ShaderNode * clone(ShaderGraph *graph) const
Definition: nodes.cpp:1238
bool empty()
Definition: image.cpp:133
int num_tiles()
Definition: image.cpp:138
ImageMetaData metadata()
Definition: image.cpp:143
int svm_slot(const int tile_index=0) const
Definition: image.cpp:154
ImageHandle add_image(const string &filename, const ImageParams &params)
Definition: image.cpp:368
bool is_float() const
Definition: image.cpp:234
InterpolationType interpolation
ExtensionType extension
ImageHandle handle
Definition: nodes.h:100
ImageParams image_params() const
Definition: nodes.cpp:275
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:348
void cull_tiles(Scene *scene, ShaderGraph *graph)
Definition: nodes.cpp:286
ShaderNode * clone(ShaderGraph *graph) const
Definition: nodes.cpp:268
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:4834
int add_ies(const string &ies)
Definition: light.cpp:1058
int add_ies_from_file(const string &filename)
Definition: light.cpp:1046
void remove_ies(int slot)
Definition: light.cpp:1095
void expand(ShaderGraph *graph)
Definition: nodes.cpp:5787
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:1941
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:6044
void expand(ShaderGraph *graph)
Definition: nodes.cpp:6028
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:4754
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:4936
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:6743
void add(ShaderNode *node, const char *name, bool isfilepath=false)
Definition: osl.cpp:1222
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
ShaderType output_type()
Definition: osl.h:163
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
bool background
Definition: osl.h:168
void parameter_color_array(const char *name, const array< float3 > &f)
Definition: osl.cpp:1270
Scene * scene
Definition: osl.h:169
void parameter_color(const char *name, float3 f)
Definition: osl.cpp:1234
string bytecode_hash
Definition: nodes.h:1644
static OSLNode * create(ShaderGraph *graph, size_t num_inputs, const OSLNode *from=NULL)
Definition: nodes.cpp:6653
ShaderNode * clone(ShaderGraph *graph) const
Definition: nodes.cpp:6648
~OSLNode()
Definition: nodes.cpp:6643
void add_output(ustring name, SocketType::Type type)
Definition: nodes.cpp:6695
char * input_default_value()
Definition: nodes.cpp:6679
string filepath
Definition: nodes.h:1643
void add_input(ustring name, SocketType::Type type)
Definition: nodes.cpp:6687
virtual void simplify_settings(Scene *scene)
Definition: nodes.cpp:5932
bool is_color
Definition: nodes.h:239
int slot
Definition: nodes.h:238
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:4282
ImageParams image_params() const
Definition: nodes.cpp:1799
ImageHandle handle
Definition: nodes.h:429
ShaderNode * clone(ShaderGraph *graph) const
Definition: nodes.cpp:1781
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:1791
bool has_bssrdf_bump()
Definition: nodes.cpp:2977
bool has_surface_bssrdf()
Definition: nodes.cpp:2838
void compile(SVMCompiler &compiler, ShaderInput *metallic, ShaderInput *subsurface, ShaderInput *subsurface_radius, ShaderInput *specular, ShaderInput *roughness, ShaderInput *specular_tint, ShaderInput *anisotropic, ShaderInput *sheen, ShaderInput *sheen_tint, ShaderInput *clearcoat, ShaderInput *clearcoat_roughness, ShaderInput *ior, ShaderInput *transmission, ShaderInput *anisotropic_rotation, ShaderInput *transmission_roughness)
Definition: nodes.cpp:2856
bool has_integrator_dependency()
Definition: nodes.cpp:2944
void expand(ShaderGraph *graph)
Definition: nodes.cpp:2783
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:2844
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:3535
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:3411
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:6548
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:1996
bool has_integrator_dependency()
Definition: nodes.cpp:2602
void simplify_settings(Scene *scene)
Definition: nodes.cpp:2565
ShaderGraph * current_graph
Definition: render/svm.h:125
void add_node(ShaderNodeType type, int a=0, int b=0, int c=0)
Definition: svm.cpp:392
bool background
Definition: render/svm.h:126
void stack_clear_offset(SocketType::Type type, int offset)
Definition: svm.cpp:251
int stack_assign_if_linked(ShaderInput *input)
Definition: svm.cpp:305
uint encode_uchar4(uint x, uint y=0, uint z=0, uint w=0)
Definition: svm.cpp:377
uint attribute_standard(ustring name)
Definition: svm.cpp:419
void stack_link(ShaderInput *input, ShaderOutput *output)
Definition: svm.cpp:321
ShaderType output_type()
Definition: render/svm.h:119
uint closure_mix_weight_offset()
Definition: render/svm.h:114
uint attribute(ustring name)
Definition: svm.cpp:409
Scene * scene
Definition: render/svm.h:124
int stack_find_offset(int size)
Definition: svm.cpp:214
int stack_assign(ShaderOutput *output)
Definition: svm.cpp:296
bool background
Definition: scene.h:183
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:5311
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:5205
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:5258
ShaderNode * add(ShaderNode *node)
Definition: graph.cpp:232
T * create_node(Args &&... args)
Definition: graph.h:351
ShaderOutput * link
Definition: graph.h:112
void disconnect()
Definition: graph.cpp:60
SocketType::Type type()
Definition: graph.h:94
const SocketType & socket_type
Definition: graph.h:110
float linear_rgb_to_gray(float3 c)
Definition: shader.cpp:769
ShaderInput * input(const char *name)
Definition: graph.cpp:111
vector< ShaderOutput * > outputs
Definition: graph.h:224
void remove_input(ShaderInput *input)
Definition: graph.cpp:149
ShaderNodeSpecialType special_type
Definition: graph.h:229
vector< ShaderInput * > inputs
Definition: graph.h:223
ShaderBump bump
Definition: graph.h:227
ShaderOutput * output(const char *name)
Definition: graph.cpp:121
virtual int get_group()
Definition: graph.h:241
virtual void compile(SVMCompiler &compiler)=0
virtual void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: graph.cpp:156
vector< ShaderInput * > links
Definition: graph.h:140
ShaderNode * parent
Definition: graph.h:139
Definition: shader.h:80
float get_sun_size()
Definition: nodes.h:194
ImageHandle handle
Definition: nodes.h:192
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:6837
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:3831
void compile_end(SVMCompiler &compiler, ShaderInput *vector_in, int vector_offset)
Definition: nodes.cpp:194
Transform compute_transform()
Definition: nodes.cpp:81
Mapping x_mapping
Definition: nodes.h:59
float3 max
Definition: nodes.h:52
bool use_minmax
Definition: nodes.h:53
Mapping z_mapping
Definition: nodes.h:59
float3 rotation
Definition: nodes.h:49
TextureMapping()
Definition: nodes.cpp:77
void compile(SVMCompiler &compiler, int offset_in, int offset_out)
Definition: nodes.cpp:155
Mapping y_mapping
Definition: nodes.h:59
float3 scale
Definition: nodes.h:50
Type type
Definition: nodes.h:56
bool skip()
Definition: nodes.cpp:138
int compile_begin(SVMCompiler &compiler, ShaderInput *vector_in)
Definition: nodes.cpp:180
float3 translation
Definition: nodes.h:48
float3 min
Definition: nodes.h:52
TextureMapping tex_mapping
Definition: nodes.h:72
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:3978
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:4626
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:7011
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:7020
void constant_fold(const ConstantFolder &folder)
Definition: nodes.cpp:6134
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:4545
void expand(ShaderGraph *graph)
Definition: nodes.cpp:4487
void attributes(Shader *shader, AttributeRequestSet *attributes)
Definition: nodes.cpp:4467
void compile(SVMCompiler &compiler, ShaderInput *param1, ShaderInput *param2)
Definition: nodes.cpp:3288
ClosureType closure
Definition: nodes.h:870
VolumeNode(const NodeType *node_type)
Definition: nodes.cpp:3283
void push_back_slow(const T &t)
Definition: util_array.h:263
CCL_NAMESPACE_BEGIN ustring u_colorspace_auto
Definition: colorspace.cpp:35
ustring u_colorspace_raw
OperationNode * node
Depsgraph * graph
StackEntry * from
Scene scene
static CCL_NAMESPACE_BEGIN const double alpha
struct @203::@204 surface
IMETHOD void random(Vector &a)
addDelta operator for displacement rotational velocity.
Definition: frames.inl:1282
uint pos
@ SHADER_SPECIAL_TYPE_PROXY
Definition: graph.h:61
@ SHADER_SPECIAL_TYPE_GEOMETRY
Definition: graph.h:63
@ SHADER_SPECIAL_TYPE_OUTPUT_AOV
Definition: graph.h:70
@ SHADER_SPECIAL_TYPE_COMBINE_CLOSURE
Definition: graph.h:67
@ SHADER_SPECIAL_TYPE_BUMP
Definition: graph.h:69
@ SHADER_SPECIAL_TYPE_AUTOCONVERT
Definition: graph.h:62
@ SHADER_SPECIAL_TYPE_OUTPUT
Definition: graph.h:68
@ SHADER_SPECIAL_TYPE_CLOSURE
Definition: graph.h:66
@ SHADER_SPECIAL_TYPE_OSL
Definition: graph.h:64
@ SHADER_BUMP_DX
Definition: graph.h:52
@ SHADER_BUMP_DY
Definition: graph.h:52
IconTextureDrawCall normal
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define cosf(x)
#define expf(x)
#define tanf(x)
#define CCL_NAMESPACE_END
#define atan2f(x, y)
#define make_float2(x, y)
#define fmodf(x, y)
#define acosf(x)
#define make_float4(x, y, z, w)
#define fabsf(x)
#define make_float3(x, y, z)
void KERNEL_FUNCTION_FULL_NAME() shader(KernelGlobals *kg, uint4 *input, float4 *output, int type, int filter, int i, int offset, int sample)
@ ATTR_STD_CURVE_INTERCEPT
Definition: kernel_types.h:759
@ ATTR_STD_GENERATED_TRANSFORM
Definition: kernel_types.h:753
@ ATTR_STD_UV
Definition: kernel_types.h:748
@ ATTR_STD_VOLUME_TEMPERATURE
Definition: kernel_types.h:767
@ ATTR_STD_VERTEX_NORMAL
Definition: kernel_types.h:746
@ ATTR_STD_UV_TANGENT
Definition: kernel_types.h:749
@ ATTR_STD_NONE
Definition: kernel_types.h:745
@ ATTR_STD_VERTEX_COLOR
Definition: kernel_types.h:751
@ ATTR_STD_VOLUME_DENSITY
Definition: kernel_types.h:763
@ ATTR_STD_VOLUME_FLAME
Definition: kernel_types.h:765
@ ATTR_STD_PTEX_FACE_ID
Definition: kernel_types.h:761
@ ATTR_STD_VOLUME_COLOR
Definition: kernel_types.h:764
@ ATTR_STD_UV_TANGENT_SIGN
Definition: kernel_types.h:750
@ ATTR_STD_CURVE_RANDOM
Definition: kernel_types.h:760
@ ATTR_STD_PTEX_UV
Definition: kernel_types.h:762
@ ATTR_STD_POINTINESS
Definition: kernel_types.h:769
@ ATTR_STD_GENERATED
Definition: kernel_types.h:752
@ ATTR_STD_RANDOM_PER_ISLAND
Definition: kernel_types.h:770
@ ATTR_STD_PARTICLE
Definition: kernel_types.h:758
static char ** types
Definition: makesdna.c:164
#define T
static void add(GHash *messages, MemArena *memarena, const Message *msg)
Definition: msgfmt.c:268
static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal)
static const pxr::TfToken metallic("metallic", pxr::TfToken::Immortal)
color rgb_ramp_lookup(color ramp[], float at, int interpolate, int extrapolate)
#define SOCKET_IN_NORMAL(name, ui_name, default_value,...)
Definition: node_type.h:338
#define SOCKET_OUT_POINT(name, ui_name)
Definition: node_type.h:385
#define SOCKET_OUT_FLOAT(name, ui_name)
Definition: node_type.h:373
#define SOCKET_OUT_COLOR(name, ui_name)
Definition: node_type.h:377
#define SOCKET_FLOAT(name, ui_name, default_value,...)
Definition: node_type.h:204
#define SOCKET_INT(name, ui_name, default_value,...)
Definition: node_type.h:200
#define SOCKET_IN_COLOR(name, ui_name, default_value,...)
Definition: node_type.h:314
#define SOCKET_FLOAT_ARRAY(name, ui_name, default_value,...)
Definition: node_type.h:252
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
Definition: node_type.h:218
#define SOCKET_OUT_NORMAL(name, ui_name)
Definition: node_type.h:389
#define SOCKET_IN_FLOAT(name, ui_name, default_value,...)
Definition: node_type.h:306
#define SOCKET_IN_CLOSURE(name, ui_name,...)
Definition: node_type.h:354
#define SOCKET_OFFSETOF(T, name)
Definition: node_type.h:181
#define SOCKET_INT_ARRAY(name, ui_name, default_value,...)
Definition: node_type.h:250
#define SOCKET_VECTOR_ARRAY(name, ui_name, default_value,...)
Definition: node_type.h:258
#define SOCKET_IN_VECTOR(name, ui_name, default_value,...)
Definition: node_type.h:322
#define SOCKET_VECTOR(name, ui_name, default_value,...)
Definition: node_type.h:208
#define SOCKET_IN_POINT(name, ui_name, default_value,...)
Definition: node_type.h:330
#define SOCKET_COLOR_ARRAY(name, ui_name, default_value,...)
Definition: node_type.h:255
#define SOCKET_COLOR(name, ui_name, default_value,...)
Definition: node_type.h:206
#define SOCKET_OUT_VECTOR(name, ui_name)
Definition: node_type.h:381
#define SOCKET_IN_STRING(name, ui_name, default_value,...)
Definition: node_type.h:346
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
Definition: node_type.h:198
#define SOCKET_IN_BOOLEAN(name, ui_name, default_value,...)
Definition: node_type.h:295
#define SOCKET_STRING(name, ui_name, default_value,...)
Definition: node_type.h:216
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition: node_type.h:220
#define SOCKET_OUT_CLOSURE(name, ui_name)
Definition: node_type.h:393
static void sky_texture_precompute_hosek(SunSky *sunsky, float3 dir, float turbidity, float ground_albedo)
Definition: nodes.cpp:714
struct SunSky SunSky
NODE_DEFINE(ImageTextureNode)
Definition: nodes.cpp:211
static float2 sky_spherical_coordinates(float3 dir)
Definition: nodes.cpp:630
static float sky_perez_function(float lam[6], float theta, float gamma)
Definition: nodes.cpp:645
#define TEXTURE_MAPPING_DEFINE(TextureNode)
Definition: nodes.cpp:45
static void sky_texture_precompute_preetham(SunSky *sunsky, float3 dir, float turbidity)
Definition: nodes.cpp:651
static void sky_texture_precompute_nishita(SunSky *sunsky, bool sun_disc, float sun_size, float sun_intensity, float sun_elevation, float sun_rotation, float altitude, float air_density, float dust_density)
Definition: nodes.cpp:755
void SKY_arhosekskymodelstate_free(SKY_ArHosekSkyModelState *state)
Definition: sky_model.cpp:290
void SKY_nishita_skymodel_precompute_sun(float sun_elevation, float angular_diameter, float altitude, float air_density, float dust_density, float *r_pixel_bottom, float *r_pixel_top)
SKY_ArHosekSkyModelState * SKY_arhosek_xyz_skymodelstate_alloc_init(const double turbidity, const double albedo, const double elevation)
Definition: sky_model.cpp:328
static const int steps
Definition: sky_nishita.cpp:28
#define min(a, b)
Definition: sort.c:51
void insert(const char *x, int y)
Definition: node_enum.h:33
vector< SocketType, std::allocator< SocketType > > inputs
Definition: node_type.h:131
void register_output(ustring name, ustring ui_name, SocketType::Type type)
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
vector< SocketType, std::allocator< SocketType > > outputs
Definition: node_type.h:132
void register_input(ustring name, ustring ui_name, SocketType::Type type, int struct_offset, const void *default_value, const NodeEnum *enum_values=NULL, const NodeType *node_type=NULL, int flags=0, int extra_flags=0)
Definition: node.h:98
float get_float(const SocketType &input) const
Definition: node.cpp:210
const NodeType * type
Definition: node.h:175
float3 get_float3(const SocketType &input) const
Definition: node.cpp:222
ustring name
Definition: node.h:174
SKY_ArHosekSkyModelConfiguration configs[11]
Definition: sky_model.h:339
Film * film
Definition: scene.h:229
vector< Geometry * > geometry
Definition: scene.h:235
SceneParams params
Definition: scene.h:264
ImageManager * image_manager
Definition: scene.h:243
ShaderManager * shader_manager
Definition: scene.h:245
Integrator * integrator
Definition: scene.h:231
LightManager * light_manager
Definition: scene.h:244
static size_t max_size()
Definition: node_type.cpp:98
static bool is_float3(Type type)
Definition: node_type.cpp:131
static ustring type_name(Type type)
Definition: node_type.cpp:109
static void * zero_default_value()
Definition: node_type.cpp:103
@ LINK_TEXTURE_UV
Definition: node_type.h:77
@ SVM_INTERNAL
Definition: node_type.h:71
@ LINK_NORMAL
Definition: node_type.h:79
@ LINK_TEXTURE_GENERATED
Definition: node_type.h:75
@ OSL_INTERNAL
Definition: node_type.h:72
@ LINK_TANGENT
Definition: node_type.h:81
@ LINK_TEXTURE_NORMAL
Definition: node_type.h:76
@ LINK_POSITION
Definition: node_type.h:80
float phi
Definition: nodes.cpp:637
float config_z[9]
Definition: nodes.cpp:641
float config_x[9]
Definition: nodes.cpp:641
float radiance_y
Definition: nodes.cpp:640
float nishita_data[10]
Definition: nodes.cpp:641
float radiance_z
Definition: nodes.cpp:640
float config_y[9]
Definition: nodes.cpp:641
float theta
Definition: nodes.cpp:637
float radiance_x
Definition: nodes.cpp:640
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
ccl_device_noinline_cpu float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2)
ccl_device_inline float3 svm_brightness_contrast(float3 color, float brightness, float contrast)
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
Definition: svm_invert.h:19
CCL_NAMESPACE_BEGIN ccl_device float3 svm_mapping(NodeMappingType type, float3 vector, float3 location, float3 rotation, float3 scale)
CCL_NAMESPACE_BEGIN ccl_device void svm_vector_math(float *value, float3 *vector, NodeVectorMathType type, float3 a, float3 b, float3 c, float param1)
Definition: svm_math_util.h:19
ccl_device float3 svm_math_blackbody_color(float t)
ccl_device float svm_math(NodeMathType type, float a, float b, float c)
ccl_device_inline float3 svm_math_gamma_color(float3 color, float gamma)
CCL_NAMESPACE_BEGIN ccl_device float fade(float t)
Definition: svm_noise.h:37
ccl_device float float_ramp_lookup(const float *ramp, float f, bool interpolate, bool extrapolate, int table_size)
Definition: svm_ramp_util.h:56
@ NODE_ENVIRONMENT_MIRROR_BALL
Definition: svm_types.h:491
@ NODE_ENVIRONMENT_EQUIRECTANGULAR
Definition: svm_types.h:490
@ NODE_INFO_OB_INDEX
Definition: svm_types.h:187
@ NODE_INFO_MAT_INDEX
Definition: svm_types.h:188
@ NODE_INFO_OB_RANDOM
Definition: svm_types.h:189
@ NODE_INFO_OB_COLOR
Definition: svm_types.h:186
@ NODE_INFO_OB_LOCATION
Definition: svm_types.h:185
@ NODE_ATTR_OUTPUT_FLOAT
Definition: svm_types.h:162
@ NODE_ATTR_OUTPUT_FLOAT_ALPHA
Definition: svm_types.h:163
@ NODE_ATTR_OUTPUT_FLOAT3
Definition: svm_types.h:161
ShaderNodeType
Definition: svm_types.h:64
@ NODE_TEX_IMAGE
Definition: svm_types.h:88
@ NODE_GEOMETRY
Definition: svm_types.h:76
@ NODE_CLOSURE_SET_WEIGHT
Definition: svm_types.h:70
@ NODE_EMISSION_WEIGHT
Definition: svm_types.h:72
@ NODE_VECTOR_TRANSFORM
Definition: svm_types.h:144
@ NODE_CLOSURE_HOLDOUT
Definition: svm_types.h:102
@ NODE_NORMAL_MAP
Definition: svm_types.h:136
@ NODE_SEPARATE_HSV
Definition: svm_types.h:141
@ NODE_SET_BUMP
Definition: svm_types.h:91
@ NODE_VERTEX_COLOR_BUMP_DX
Definition: svm_types.h:94
@ NODE_CLOSURE_VOLUME
Definition: svm_types.h:105
@ NODE_TEX_WHITE_NOISE
Definition: svm_types.h:129
@ NODE_TEX_MUSGRAVE
Definition: svm_types.h:124
@ NODE_MIX
Definition: svm_types.h:138
@ NODE_NORMAL
Definition: svm_types.h:130
@ NODE_INVERT
Definition: svm_types.h:137
@ NODE_SET_DISPLACEMENT
Definition: svm_types.h:85
@ NODE_DISPLACEMENT
Definition: svm_types.h:86
@ NODE_VALUE_V
Definition: svm_types.h:80
@ NODE_TEX_WAVE
Definition: svm_types.h:125
@ NODE_CLOSURE_EMISSION
Definition: svm_types.h:68
@ NODE_HAIR_INFO
Definition: svm_types.h:115
@ NODE_MATH
Definition: svm_types.h:107
@ NODE_TEX_ENVIRONMENT
Definition: svm_types.h:120
@ NODE_WAVELENGTH
Definition: svm_types.h:146
@ NODE_MIX_CLOSURE
Definition: svm_types.h:73
@ NODE_CLOSURE_BACKGROUND
Definition: svm_types.h:69
@ NODE_SEPARATE_VECTOR
Definition: svm_types.h:139
@ NODE_IES
Definition: svm_types.h:132
@ NODE_HSV
Definition: svm_types.h:101
@ NODE_VECTOR_CURVES
Definition: svm_types.h:134
@ NODE_CONVERT
Definition: svm_types.h:77
@ NODE_TEX_COORD_BUMP_DY
Definition: svm_types.h:97
@ NODE_CAMERA
Definition: svm_types.h:119
@ NODE_MAPPING
Definition: svm_types.h:117
@ NODE_BRIGHTCONTRAST
Definition: svm_types.h:111
@ NODE_PRINCIPLED_VOLUME
Definition: svm_types.h:106
@ NODE_TEX_MAGIC
Definition: svm_types.h:126
@ NODE_VERTEX_COLOR
Definition: svm_types.h:82
@ NODE_FRESNEL
Definition: svm_types.h:103
@ NODE_VALUE_F
Definition: svm_types.h:79
@ NODE_TEX_CHECKER
Definition: svm_types.h:127
@ NODE_PARTICLE_INFO
Definition: svm_types.h:114
@ NODE_OBJECT_INFO
Definition: svm_types.h:113
@ NODE_LAYER_WEIGHT
Definition: svm_types.h:104
@ NODE_TEX_VOXEL
Definition: svm_types.h:152
@ NODE_VECTOR_DISPLACEMENT
Definition: svm_types.h:87
@ NODE_CLAMP
Definition: svm_types.h:149
@ NODE_GEOMETRY_BUMP_DY
Definition: svm_types.h:84
@ NODE_VECTOR_MATH
Definition: svm_types.h:108
@ NODE_CLOSURE_SET_NORMAL
Definition: svm_types.h:98
@ NODE_ATTR_BUMP_DX
Definition: svm_types.h:92
@ NODE_LIGHT_FALLOFF
Definition: svm_types.h:131
@ NODE_VERTEX_COLOR_BUMP_DY
Definition: svm_types.h:95
@ NODE_TEX_BRICK
Definition: svm_types.h:128
@ NODE_AOV_COLOR
Definition: svm_types.h:154
@ NODE_MIN_MAX
Definition: svm_types.h:118
@ NODE_COMBINE_HSV
Definition: svm_types.h:142
@ NODE_ATTR
Definition: svm_types.h:81
@ NODE_TEX_COORD_BUMP_DX
Definition: svm_types.h:96
@ NODE_CLOSURE_WEIGHT
Definition: svm_types.h:71
@ NODE_VECTOR_ROTATE
Definition: svm_types.h:143
@ NODE_COMBINE_VECTOR
Definition: svm_types.h:140
@ NODE_GAMMA
Definition: svm_types.h:110
@ NODE_TEX_IMAGE_BOX
Definition: svm_types.h:89
@ NODE_TANGENT
Definition: svm_types.h:135
@ NODE_TEX_GRADIENT
Definition: svm_types.h:122
@ NODE_AMBIENT_OCCLUSION
Definition: svm_types.h:151
@ NODE_WIREFRAME
Definition: svm_types.h:145
@ NODE_CLOSURE_BSDF
Definition: svm_types.h:67
@ NODE_AOV_VALUE
Definition: svm_types.h:155
@ NODE_ATTR_BUMP_DY
Definition: svm_types.h:93
@ NODE_TEX_COORD
Definition: svm_types.h:78
@ NODE_BEVEL
Definition: svm_types.h:150
@ NODE_BLACKBODY
Definition: svm_types.h:147
@ NODE_MAP_RANGE
Definition: svm_types.h:148
@ NODE_GEOMETRY_BUMP_DX
Definition: svm_types.h:83
@ NODE_TEX_SKY
Definition: svm_types.h:121
@ NODE_RGB_CURVES
Definition: svm_types.h:133
@ NODE_TEX_NOISE
Definition: svm_types.h:90
@ NODE_TEX_VORONOI
Definition: svm_types.h:123
@ NODE_RGB_RAMP
Definition: svm_types.h:109
@ NODE_TEXTURE_MAPPING
Definition: svm_types.h:116
@ NODE_LIGHT_PATH
Definition: svm_types.h:112
@ NODE_MUSGRAVE_MULTIFRACTAL
Definition: svm_types.h:397
@ NODE_MUSGRAVE_RIDGED_MULTIFRACTAL
Definition: svm_types.h:400
@ NODE_MUSGRAVE_HYBRID_MULTIFRACTAL
Definition: svm_types.h:399
@ NODE_MUSGRAVE_HETERO_TERRAIN
Definition: svm_types.h:401
@ NODE_MUSGRAVE_FBM
Definition: svm_types.h:398
NodeBumpOffset
Definition: svm_types.h:494
@ NODE_BUMP_OFFSET_DY
Definition: svm_types.h:497
@ NODE_BUMP_OFFSET_CENTER
Definition: svm_types.h:495
@ NODE_BUMP_OFFSET_DX
Definition: svm_types.h:496
@ NODE_WAVE_BANDS_DIRECTION_Z
Definition: svm_types.h:409
@ NODE_WAVE_BANDS_DIRECTION_DIAGONAL
Definition: svm_types.h:410
@ NODE_WAVE_BANDS_DIRECTION_Y
Definition: svm_types.h:408
@ NODE_WAVE_BANDS_DIRECTION_X
Definition: svm_types.h:407
NodeMappingType
Definition: svm_types.h:358
@ NODE_INFO_CURVE_IS_STRAND
Definition: svm_types.h:205
@ NODE_INFO_CURVE_TANGENT_NORMAL
Definition: svm_types.h:210
@ NODE_INFO_CURVE_THICKNESS
Definition: svm_types.h:207
@ NODE_AO_INSIDE
Definition: svm_types.h:507
@ NODE_AO_GLOBAL_RADIUS
Definition: svm_types.h:508
@ NODE_AO_ONLY_LOCAL
Definition: svm_types.h:506
@ NODE_VECTOR_TRANSFORM_CONVERT_SPACE_OBJECT
Definition: svm_types.h:381
@ NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD
Definition: svm_types.h:380
@ NODE_VECTOR_TRANSFORM_CONVERT_SPACE_CAMERA
Definition: svm_types.h:382
@ NODE_TANGENT_AXIS_Y
Definition: svm_types.h:465
@ NODE_TANGENT_AXIS_X
Definition: svm_types.h:464
@ NODE_TANGENT_AXIS_Z
Definition: svm_types.h:466
@ NODE_PRINCIPLED_HAIR_REFLECTANCE
Definition: svm_types.h:519
@ NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION
Definition: svm_types.h:521
@ NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION
Definition: svm_types.h:520
@ NODE_TEXCO_VOLUME_GENERATED
Definition: svm_types.h:246
@ NODE_TEXCO_REFLECTION
Definition: svm_types.h:243
@ NODE_TEXCO_WINDOW
Definition: svm_types.h:242
@ NODE_TEXCO_OBJECT
Definition: svm_types.h:240
@ NODE_TEXCO_DUPLI_UV
Definition: svm_types.h:245
@ NODE_TEXCO_DUPLI_GENERATED
Definition: svm_types.h:244
@ NODE_TEXCO_CAMERA
Definition: svm_types.h:241
@ NODE_TEXCO_NORMAL
Definition: svm_types.h:239
@ SHADER_TYPE_SURFACE
Definition: svm_types.h:512
@ SHADER_TYPE_VOLUME
Definition: svm_types.h:513
@ SHADER_TYPE_DISPLACEMENT
Definition: svm_types.h:514
@ NODE_VORONOI_SMOOTH_F1
Definition: svm_types.h:448
@ NODE_VORONOI_N_SPHERE_RADIUS
Definition: svm_types.h:450
@ NODE_VORONOI_F1
Definition: svm_types.h:446
@ NODE_VORONOI_F2
Definition: svm_types.h:447
@ NODE_VORONOI_DISTANCE_TO_EDGE
Definition: svm_types.h:449
@ NODE_GEOM_N
Definition: svm_types.h:177
@ NODE_GEOM_T
Definition: svm_types.h:178
@ NODE_GEOM_uv
Definition: svm_types.h:181
@ NODE_GEOM_P
Definition: svm_types.h:176
@ NODE_GEOM_Ng
Definition: svm_types.h:180
@ NODE_GEOM_I
Definition: svm_types.h:179
@ NODE_INFO_PAR_SIZE
Definition: svm_types.h:199
@ NODE_INFO_PAR_LOCATION
Definition: svm_types.h:197
@ NODE_INFO_PAR_RANDOM
Definition: svm_types.h:194
@ NODE_INFO_PAR_VELOCITY
Definition: svm_types.h:200
@ NODE_INFO_PAR_INDEX
Definition: svm_types.h:193
@ NODE_INFO_PAR_ANGULAR_VELOCITY
Definition: svm_types.h:201
@ NODE_INFO_PAR_AGE
Definition: svm_types.h:195
@ NODE_INFO_PAR_LIFETIME
Definition: svm_types.h:196
@ NODE_INFO_PAR_ROTATION
Definition: svm_types.h:198
@ NODE_WAVE_BANDS
Definition: svm_types.h:404
@ NODE_WAVE_RINGS
Definition: svm_types.h:404
@ NODE_IMAGE_COMPRESS_AS_SRGB
Definition: svm_types.h:485
@ NODE_IMAGE_ALPHA_UNASSOCIATE
Definition: svm_types.h:486
@ NODE_VORONOI_EUCLIDEAN
Definition: svm_types.h:439
@ NODE_VORONOI_MANHATTAN
Definition: svm_types.h:440
@ NODE_VORONOI_CHEBYCHEV
Definition: svm_types.h:441
@ NODE_VORONOI_MINKOWSKI
Definition: svm_types.h:442
@ NODE_SKY_PREETHAM
Definition: svm_types.h:426
@ NODE_SKY_NISHITA
Definition: svm_types.h:426
@ NODE_SKY_HOSEK
Definition: svm_types.h:426
@ NODE_WAVE_PROFILE_TRI
Definition: svm_types.h:423
@ NODE_WAVE_PROFILE_SIN
Definition: svm_types.h:421
@ NODE_WAVE_PROFILE_SAW
Definition: svm_types.h:422
@ NODE_TEX_VOXEL_SPACE_WORLD
Definition: svm_types.h:502
@ NODE_TEX_VOXEL_SPACE_OBJECT
Definition: svm_types.h:501
@ NODE_MIX_DIV
Definition: svm_types.h:255
@ NODE_MIX_SOFT
Definition: svm_types.h:266
@ NODE_MIX_CLAMP
Definition: svm_types.h:268
@ NODE_MIX_LIGHT
Definition: svm_types.h:258
@ NODE_MIX_MUL
Definition: svm_types.h:252
@ NODE_MIX_DIFF
Definition: svm_types.h:256
@ NODE_MIX_BURN
Definition: svm_types.h:261
@ NODE_MIX_SUB
Definition: svm_types.h:253
@ NODE_MIX_LINEAR
Definition: svm_types.h:267
@ NODE_MIX_DARK
Definition: svm_types.h:257
@ NODE_MIX_SAT
Definition: svm_types.h:263
@ NODE_MIX_COLOR
Definition: svm_types.h:265
@ NODE_MIX_SCREEN
Definition: svm_types.h:254
@ NODE_MIX_HUE
Definition: svm_types.h:262
@ NODE_MIX_BLEND
Definition: svm_types.h:250
@ NODE_MIX_OVERLAY
Definition: svm_types.h:259
@ NODE_MIX_DODGE
Definition: svm_types.h:260
@ NODE_MIX_VAL
Definition: svm_types.h:264
@ NODE_MIX_ADD
Definition: svm_types.h:251
@ NODE_LP_ray_depth
Definition: svm_types.h:225
@ NODE_LP_shadow
Definition: svm_types.h:216
@ NODE_LP_backfacing
Definition: svm_types.h:223
@ NODE_LP_ray_glossy
Definition: svm_types.h:227
@ NODE_LP_camera
Definition: svm_types.h:215
@ NODE_LP_glossy
Definition: svm_types.h:218
@ NODE_LP_transmission
Definition: svm_types.h:221
@ NODE_LP_singular
Definition: svm_types.h:219
@ NODE_LP_diffuse
Definition: svm_types.h:217
@ NODE_LP_ray_diffuse
Definition: svm_types.h:226
@ NODE_LP_volume_scatter
Definition: svm_types.h:222
@ NODE_LP_ray_transmission
Definition: svm_types.h:229
@ NODE_LP_ray_length
Definition: svm_types.h:224
@ NODE_LP_ray_transparent
Definition: svm_types.h:228
@ NODE_LP_reflection
Definition: svm_types.h:220
#define SVM_STACK_INVALID
Definition: svm_types.h:27
#define NODE_GROUP_LEVEL_1
Definition: svm_types.h:42
@ CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID
Definition: svm_types.h:559
@ CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID
Definition: svm_types.h:587
@ CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID
Definition: svm_types.h:550
@ CLOSURE_BSSRDF_CUBIC_ID
Definition: svm_types.h:574
@ CLOSURE_BSDF_HAIR_PRINCIPLED_ID
Definition: svm_types.h:565
@ CLOSURE_BSSRDF_GAUSSIAN_ID
Definition: svm_types.h:575
@ CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID
Definition: svm_types.h:562
@ CLOSURE_BSDF_DIFFUSE_ID
Definition: svm_types.h:534
@ CLOSURE_BSSRDF_BURLEY_ID
Definition: svm_types.h:577
@ CLOSURE_BSDF_PRINCIPLED_ID
Definition: svm_types.h:589
@ CLOSURE_BSDF_TRANSPARENT_ID
Definition: svm_types.h:571
@ CLOSURE_BSDF_DIFFUSE_TOON_ID
Definition: svm_types.h:539
@ CLOSURE_BSDF_MICROFACET_GGX_ID
Definition: svm_types.h:544
@ CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID
Definition: svm_types.h:558
@ CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID
Definition: svm_types.h:548
@ CLOSURE_BSDF_HAIR_TRANSMISSION_ID
Definition: svm_types.h:566
@ CLOSURE_BSDF_SHARP_GLASS_ID
Definition: svm_types.h:564
@ CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID
Definition: svm_types.h:561
@ CLOSURE_BSSRDF_RANDOM_WALK_ID
Definition: svm_types.h:578
@ CLOSURE_BSDF_REFRACTION_ID
Definition: svm_types.h:557
@ CLOSURE_BSDF_MICROFACET_BECKMANN_ID
Definition: svm_types.h:547
@ CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID
Definition: svm_types.h:560
@ CLOSURE_BSSRDF_PRINCIPLED_ID
Definition: svm_types.h:576
@ CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID
Definition: svm_types.h:579
@ NBUILTIN_CLOSURES
Definition: svm_types.h:591
@ CLOSURE_BSDF_GLOSSY_TOON_ID
Definition: svm_types.h:553
@ CLOSURE_VOLUME_ABSORPTION_ID
Definition: svm_types.h:586
@ CLOSURE_BSDF_HAIR_REFLECTION_ID
Definition: svm_types.h:554
@ CLOSURE_BSDF_TRANSLUCENT_ID
Definition: svm_types.h:540
@ CLOSURE_BSDF_REFLECTION_ID
Definition: svm_types.h:543
@ CLOSURE_BSDF_ASHIKHMIN_VELVET_ID
Definition: svm_types.h:551
@ NODE_VECTOR_TRANSFORM_TYPE_NORMAL
Definition: svm_types.h:376
@ NODE_VECTOR_TRANSFORM_TYPE_VECTOR
Definition: svm_types.h:374
@ NODE_VECTOR_TRANSFORM_TYPE_POINT
Definition: svm_types.h:375
@ NODE_IMAGE_PROJ_SPHERE
Definition: svm_types.h:480
@ NODE_IMAGE_PROJ_TUBE
Definition: svm_types.h:481
@ NODE_IMAGE_PROJ_BOX
Definition: svm_types.h:479
@ NODE_IMAGE_PROJ_FLAT
Definition: svm_types.h:478
@ NODE_BLEND_QUADRATIC
Definition: svm_types.h:430
@ NODE_BLEND_DIAGONAL
Definition: svm_types.h:432
@ NODE_BLEND_EASING
Definition: svm_types.h:431
@ NODE_BLEND_RADIAL
Definition: svm_types.h:433
@ NODE_BLEND_SPHERICAL
Definition: svm_types.h:435
@ NODE_BLEND_QUADRATIC_SPHERE
Definition: svm_types.h:434
@ NODE_BLEND_LINEAR
Definition: svm_types.h:429
#define CLOSURE_WEIGHT_CUTOFF
Definition: svm_types.h:637
@ NODE_TANGENT_RADIAL
Definition: svm_types.h:459
@ NODE_TANGENT_UVMAP
Definition: svm_types.h:460
@ NODE_WAVE_RINGS_DIRECTION_Y
Definition: svm_types.h:415
@ NODE_WAVE_RINGS_DIRECTION_SPHERICAL
Definition: svm_types.h:417
@ NODE_WAVE_RINGS_DIRECTION_X
Definition: svm_types.h:414
@ NODE_WAVE_RINGS_DIRECTION_Z
Definition: svm_types.h:416
@ NODE_LAYER_WEIGHT_FACING
Definition: svm_types.h:455
@ NODE_LAYER_WEIGHT_FRESNEL
Definition: svm_types.h:454
@ NODE_NORMAL_MAP_TANGENT
Definition: svm_types.h:470
@ NODE_NORMAL_MAP_WORLD
Definition: svm_types.h:472
@ NODE_NORMAL_MAP_BLENDER_WORLD
Definition: svm_types.h:474
@ NODE_NORMAL_MAP_BLENDER_OBJECT
Definition: svm_types.h:473
@ NODE_NORMAL_MAP_OBJECT
Definition: svm_types.h:471
@ NODE_CONVERT_IF
Definition: svm_types.h:392
@ NODE_CONVERT_CI
Definition: svm_types.h:389
@ NODE_CONVERT_CF
Definition: svm_types.h:388
@ NODE_CONVERT_VF
Definition: svm_types.h:390
@ NODE_CONVERT_VI
Definition: svm_types.h:391
@ NODE_CONVERT_FI
Definition: svm_types.h:387
@ NODE_CONVERT_IV
Definition: svm_types.h:393
@ NODE_CONVERT_FV
Definition: svm_types.h:386
@ NODE_LIGHT_FALLOFF_QUADRATIC
Definition: svm_types.h:233
@ NODE_LIGHT_FALLOFF_LINEAR
Definition: svm_types.h:234
@ NODE_LIGHT_FALLOFF_CONSTANT
Definition: svm_types.h:235
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
float max
#define mix(a, b, c)
Definition: util_hash.h:30
#define VLOG(severity)
Definition: util_logging.h:50
ccl_device_inline uint __float_as_uint(float f)
Definition: util_math.h:222
ccl_device_inline int __float_as_int(float f)
Definition: util_math.h:202
#define M_PI_2_F
Definition: util_math.h:46
#define M_2PI_F
Definition: util_math.h:69
ccl_device_inline float4 float3_to_float4(const float3 a)
Definition: util_math.h:420
#define M_PI_F
Definition: util_math.h:43
ccl_device_inline int clamp(int a, int mn, int mx)
Definition: util_math.h:283
ccl_device_inline float distance(const float2 &a, const float2 &b)
ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t)
ccl_device_inline float average(const float2 &a)
ccl_device_inline float3 one_float3()
ccl_device_inline float3 zero_float3()
#define T2
Definition: util_md5.cpp:36
bool string_endswith(const string &s, const string &end)
@ IMAGE_ALPHA_ASSOCIATED
Definition: util_texture.h:70
@ IMAGE_ALPHA_CHANNEL_PACKED
Definition: util_texture.h:71
@ IMAGE_ALPHA_AUTO
Definition: util_texture.h:73
@ IMAGE_ALPHA_IGNORE
Definition: util_texture.h:72
@ IMAGE_ALPHA_UNASSOCIATED
Definition: util_texture.h:69
#define TEX_IMAGE_MISSING_R
Definition: util_texture.h:28
#define TEX_IMAGE_MISSING_B
Definition: util_texture.h:30
@ INTERPOLATION_LINEAR
Definition: util_texture.h:40
@ INTERPOLATION_SMART
Definition: util_texture.h:43
@ INTERPOLATION_CLOSEST
Definition: util_texture.h:41
@ INTERPOLATION_CUBIC
Definition: util_texture.h:42
@ EXTENSION_REPEAT
Definition: util_texture.h:86
@ EXTENSION_CLIP
Definition: util_texture.h:90
@ EXTENSION_EXTEND
Definition: util_texture.h:88
#define TEX_IMAGE_MISSING_G
Definition: util_texture.h:29
Transform transform_transposed_inverse(const Transform &tfm)
Transform transform_inverse(const Transform &tfm)
ccl_device_inline Transform transform_identity()
ccl_device_inline Transform transform_euler(float3 euler)
ccl_device_inline Transform transform_translate(float3 t)
ccl_device_inline Transform transform_scale(float3 s)
ccl_device_inline size_t align_up(size_t offset, size_t alignment)
Definition: util_types.h:65
ccl_device_inline size_t divide_up(size_t x, size_t y)
Definition: util_types.h:70