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