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 #ifndef __NODES_H__
18 #define __NODES_H__
19 
20 #include "graph/node.h"
21 #include "render/graph.h"
22 #include "render/image.h"
23 
24 #include "util/util_array.h"
25 #include "util/util_string.h"
26 
27 CCL_NAMESPACE_BEGIN
28 
29 class ImageManager;
30 class LightManager;
31 class Scene;
32 class Shader;
33 
34 /* Texture Mapping */
35 
36 class TextureMapping {
37  public:
38   TextureMapping();
39   Transform compute_transform();
40   bool skip();
41   void compile(SVMCompiler &compiler, int offset_in, int offset_out);
42   int compile(SVMCompiler &compiler, ShaderInput *vector_in);
43   void compile(OSLCompiler &compiler);
44 
45   int compile_begin(SVMCompiler &compiler, ShaderInput *vector_in);
46   void compile_end(SVMCompiler &compiler, ShaderInput *vector_in, int vector_offset);
47 
48   float3 translation;
49   float3 rotation;
50   float3 scale;
51 
52   float3 min, max;
53   bool use_minmax;
54 
55   enum Type { POINT = 0, TEXTURE = 1, VECTOR = 2, NORMAL = 3 };
56   Type type;
57 
58   enum Mapping { NONE = 0, X = 1, Y = 2, Z = 3 };
59   Mapping x_mapping, y_mapping, z_mapping;
60 
61   enum Projection { FLAT, CUBE, TUBE, SPHERE };
62   Projection projection;
63 };
64 
65 /* Nodes */
66 
67 class TextureNode : public ShaderNode {
68  public:
TextureNode(const NodeType * node_type)69   explicit TextureNode(const NodeType *node_type) : ShaderNode(node_type)
70   {
71   }
72   TextureMapping tex_mapping;
73 };
74 
75 /* Any node which uses image manager's slot should be a subclass of this one. */
76 class ImageSlotTextureNode : public TextureNode {
77  public:
ImageSlotTextureNode(const NodeType * node_type)78   explicit ImageSlotTextureNode(const NodeType *node_type) : TextureNode(node_type)
79   {
80     special_type = SHADER_SPECIAL_TYPE_IMAGE_SLOT;
81   }
82 
equals(const ShaderNode & other)83   virtual bool equals(const ShaderNode &other)
84   {
85     const ImageSlotTextureNode &other_node = (const ImageSlotTextureNode &)other;
86     return TextureNode::equals(other) && handle == other_node.handle;
87   }
88 
89   ImageHandle handle;
90 };
91 
92 class ImageTextureNode : public ImageSlotTextureNode {
93  public:
94   SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode)
95   ShaderNode *clone(ShaderGraph *graph) const;
96   void attributes(Shader *shader, AttributeRequestSet *attributes);
has_attribute_dependency()97   bool has_attribute_dependency()
98   {
99     return true;
100   }
101 
equals(const ShaderNode & other)102   virtual bool equals(const ShaderNode &other)
103   {
104     const ImageTextureNode &other_node = (const ImageTextureNode &)other;
105     return ImageSlotTextureNode::equals(other) && animated == other_node.animated;
106   }
107 
108   ImageParams image_params() const;
109 
110   /* Parameters. */
111   ustring filename;
112   ustring colorspace;
113   ImageAlphaType alpha_type;
114   NodeImageProjection projection;
115   InterpolationType interpolation;
116   ExtensionType extension;
117   float projection_blend;
118   bool animated;
119   float3 vector;
120   ccl::vector<int> tiles;
121 
122  protected:
123   void cull_tiles(Scene *scene, ShaderGraph *graph);
124 };
125 
126 class EnvironmentTextureNode : public ImageSlotTextureNode {
127  public:
128   SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode)
129   ShaderNode *clone(ShaderGraph *graph) const;
130   void attributes(Shader *shader, AttributeRequestSet *attributes);
has_attribute_dependency()131   bool has_attribute_dependency()
132   {
133     return true;
134   }
get_group()135   virtual int get_group()
136   {
137     return NODE_GROUP_LEVEL_2;
138   }
139 
equals(const ShaderNode & other)140   virtual bool equals(const ShaderNode &other)
141   {
142     const EnvironmentTextureNode &other_node = (const EnvironmentTextureNode &)other;
143     return ImageSlotTextureNode::equals(other) && animated == other_node.animated;
144   }
145 
146   ImageParams image_params() const;
147 
148   /* Parameters. */
149   ustring filename;
150   ustring colorspace;
151   ImageAlphaType alpha_type;
152   NodeEnvironmentProjection projection;
153   InterpolationType interpolation;
154   bool animated;
155   float3 vector;
156 };
157 
158 class SkyTextureNode : public TextureNode {
159  public:
SHADER_NODE_CLASS(SkyTextureNode)160   SHADER_NODE_CLASS(SkyTextureNode)
161 
162   virtual int get_group()
163   {
164     return NODE_GROUP_LEVEL_2;
165   }
166 
167   NodeSkyType type;
168   float3 sun_direction;
169   float turbidity;
170   float ground_albedo;
171   bool sun_disc;
172   float sun_size;
173   float sun_intensity;
174   float sun_elevation;
175   float sun_rotation;
176   float altitude;
177   float air_density;
178   float dust_density;
179   float ozone_density;
180   float3 vector;
181   ImageHandle handle;
182 
get_sun_size()183   float get_sun_size()
184   {
185     /* Clamping for numerical precision. */
186     return fmaxf(sun_size, 0.0005f);
187   }
188 };
189 
190 class OutputNode : public ShaderNode {
191  public:
192   SHADER_NODE_CLASS(OutputNode)
193 
194   void *surface;
195   void *volume;
196   float3 displacement;
197   float3 normal;
198 
199   /* Don't allow output node de-duplication. */
equals(const ShaderNode &)200   virtual bool equals(const ShaderNode & /*other*/)
201   {
202     return false;
203   }
204 };
205 
206 class OutputAOVNode : public ShaderNode {
207  public:
208   SHADER_NODE_CLASS(OutputAOVNode)
209   virtual void simplify_settings(Scene *scene);
210 
211   float value;
212   float3 color;
213 
214   ustring name;
215 
get_group()216   virtual int get_group()
217   {
218     return NODE_GROUP_LEVEL_4;
219   }
220 
221   /* Don't allow output node de-duplication. */
equals(const ShaderNode &)222   virtual bool equals(const ShaderNode & /*other*/)
223   {
224     return false;
225   }
226 
227   int slot;
228   bool is_color;
229 };
230 
231 class GradientTextureNode : public TextureNode {
232  public:
SHADER_NODE_CLASS(GradientTextureNode)233   SHADER_NODE_CLASS(GradientTextureNode)
234 
235   virtual int get_group()
236   {
237     return NODE_GROUP_LEVEL_2;
238   }
239 
240   NodeGradientType type;
241   float3 vector;
242 };
243 
244 class NoiseTextureNode : public TextureNode {
245  public:
246   SHADER_NODE_CLASS(NoiseTextureNode)
247 
248   int dimensions;
249   float w, scale, detail, roughness, distortion;
250   float3 vector;
251 };
252 
253 class VoronoiTextureNode : public TextureNode {
254  public:
SHADER_NODE_CLASS(VoronoiTextureNode)255   SHADER_NODE_CLASS(VoronoiTextureNode)
256 
257   virtual int get_group()
258   {
259     return NODE_GROUP_LEVEL_2;
260   }
261 
get_feature()262   virtual int get_feature()
263   {
264     int result = ShaderNode::get_feature();
265     if (dimensions == 4) {
266       result |= NODE_FEATURE_VORONOI_EXTRA;
267     }
268     else if (dimensions >= 2 && feature == NODE_VORONOI_SMOOTH_F1) {
269       result |= NODE_FEATURE_VORONOI_EXTRA;
270     }
271     return result;
272   }
273 
274   int dimensions;
275   NodeVoronoiDistanceMetric metric;
276   NodeVoronoiFeature feature;
277   float w, scale, exponent, smoothness, randomness;
278   float3 vector;
279 };
280 
281 class MusgraveTextureNode : public TextureNode {
282  public:
SHADER_NODE_CLASS(MusgraveTextureNode)283   SHADER_NODE_CLASS(MusgraveTextureNode)
284 
285   virtual int get_group()
286   {
287     return NODE_GROUP_LEVEL_2;
288   }
289 
290   int dimensions;
291   NodeMusgraveType type;
292   float w, scale, detail, dimension, lacunarity, offset, gain;
293   float3 vector;
294 };
295 
296 class WaveTextureNode : public TextureNode {
297  public:
SHADER_NODE_CLASS(WaveTextureNode)298   SHADER_NODE_CLASS(WaveTextureNode)
299 
300   virtual int get_group()
301   {
302     return NODE_GROUP_LEVEL_2;
303   }
304 
305   NodeWaveType type;
306   NodeWaveBandsDirection bands_direction;
307   NodeWaveRingsDirection rings_direction;
308   NodeWaveProfile profile;
309 
310   float scale, distortion, detail, detail_scale, detail_roughness, phase;
311   float3 vector;
312 };
313 
314 class MagicTextureNode : public TextureNode {
315  public:
SHADER_NODE_CLASS(MagicTextureNode)316   SHADER_NODE_CLASS(MagicTextureNode)
317 
318   virtual int get_group()
319   {
320     return NODE_GROUP_LEVEL_2;
321   }
322 
323   int depth;
324   float3 vector;
325   float scale, distortion;
326 };
327 
328 class CheckerTextureNode : public TextureNode {
329  public:
330   SHADER_NODE_CLASS(CheckerTextureNode)
331 
332   float3 vector, color1, color2;
333   float scale;
334 
get_group()335   virtual int get_group()
336   {
337     return NODE_GROUP_LEVEL_2;
338   }
339 };
340 
341 class BrickTextureNode : public TextureNode {
342  public:
343   SHADER_NODE_CLASS(BrickTextureNode)
344 
345   float offset, squash;
346   int offset_frequency, squash_frequency;
347 
348   float3 color1, color2, mortar;
349   float scale, mortar_size, mortar_smooth, bias, brick_width, row_height;
350   float3 vector;
351 
get_group()352   virtual int get_group()
353   {
354     return NODE_GROUP_LEVEL_2;
355   }
356 };
357 
358 class PointDensityTextureNode : public ShaderNode {
359  public:
SHADER_NODE_NO_CLONE_CLASS(PointDensityTextureNode)360   SHADER_NODE_NO_CLONE_CLASS(PointDensityTextureNode)
361   virtual int get_group()
362   {
363     return NODE_GROUP_LEVEL_4;
364   }
365 
366   ~PointDensityTextureNode();
367   ShaderNode *clone(ShaderGraph *graph) const;
368   void attributes(Shader *shader, AttributeRequestSet *attributes);
has_attribute_dependency()369   bool has_attribute_dependency()
370   {
371     return true;
372   }
373 
has_spatial_varying()374   bool has_spatial_varying()
375   {
376     return true;
377   }
378 
379   /* Parameters. */
380   ustring filename;
381   NodeTexVoxelSpace space;
382   InterpolationType interpolation;
383   Transform tfm;
384   float3 vector;
385 
386   /* Runtime. */
387   ImageHandle handle;
388 
389   ImageParams image_params() const;
390 
equals(const ShaderNode & other)391   virtual bool equals(const ShaderNode &other)
392   {
393     const PointDensityTextureNode &other_node = (const PointDensityTextureNode &)other;
394     return ShaderNode::equals(other) && handle == other_node.handle;
395   }
396 };
397 
398 class IESLightNode : public TextureNode {
399  public:
400   SHADER_NODE_NO_CLONE_CLASS(IESLightNode)
401 
402   ~IESLightNode();
403   ShaderNode *clone(ShaderGraph *graph) const;
get_group()404   virtual int get_group()
405   {
406     return NODE_GROUP_LEVEL_2;
407   }
408 
409   ustring filename;
410   ustring ies;
411 
412   float strength;
413   float3 vector;
414 
415  private:
416   LightManager *light_manager;
417   int slot;
418 
419   void get_slot();
420 };
421 
422 class WhiteNoiseTextureNode : public ShaderNode {
423  public:
SHADER_NODE_CLASS(WhiteNoiseTextureNode)424   SHADER_NODE_CLASS(WhiteNoiseTextureNode)
425   virtual int get_group()
426   {
427     return NODE_GROUP_LEVEL_2;
428   }
429 
430   int dimensions;
431   float3 vector;
432   float w;
433 };
434 
435 class MappingNode : public ShaderNode {
436  public:
SHADER_NODE_CLASS(MappingNode)437   SHADER_NODE_CLASS(MappingNode)
438   virtual int get_group()
439   {
440     return NODE_GROUP_LEVEL_2;
441   }
442   void constant_fold(const ConstantFolder &folder);
443 
444   float3 vector, location, rotation, scale;
445   NodeMappingType type;
446 };
447 
448 class RGBToBWNode : public ShaderNode {
449  public:
450   SHADER_NODE_CLASS(RGBToBWNode)
451   void constant_fold(const ConstantFolder &folder);
452 
453   float3 color;
454 };
455 
456 class ConvertNode : public ShaderNode {
457  public:
458   ConvertNode(SocketType::Type from, SocketType::Type to, bool autoconvert = false);
459   SHADER_NODE_BASE_CLASS(ConvertNode)
460 
461   void constant_fold(const ConstantFolder &folder);
462 
463   SocketType::Type from, to;
464 
465   union {
466     float value_float;
467     int value_int;
468     float3 value_color;
469     float3 value_vector;
470     float3 value_point;
471     float3 value_normal;
472   };
473   ustring value_string;
474 
475  private:
476   static const int MAX_TYPE = 12;
477   static bool register_types();
478   static Node *create(const NodeType *type);
479   static const NodeType *node_types[MAX_TYPE][MAX_TYPE];
480   static bool initialized;
481 };
482 
483 class BsdfBaseNode : public ShaderNode {
484  public:
485   BsdfBaseNode(const NodeType *node_type);
486 
has_spatial_varying()487   bool has_spatial_varying()
488   {
489     return true;
490   }
get_closure_type()491   virtual ClosureType get_closure_type()
492   {
493     return closure;
494   }
495   virtual bool has_bump();
496 
equals(const ShaderNode &)497   virtual bool equals(const ShaderNode & /*other*/)
498   {
499     /* TODO(sergey): With some care BSDF nodes can be de-duplicated. */
500     return false;
501   }
502 
503   ClosureType closure;
504 };
505 
506 class BsdfNode : public BsdfBaseNode {
507  public:
508   explicit BsdfNode(const NodeType *node_type);
509   SHADER_NODE_BASE_CLASS(BsdfNode)
510 
511   void compile(SVMCompiler &compiler,
512                ShaderInput *param1,
513                ShaderInput *param2,
514                ShaderInput *param3 = NULL,
515                ShaderInput *param4 = NULL);
516 
517   float3 color;
518   float3 normal;
519   float surface_mix_weight;
520 };
521 
522 class AnisotropicBsdfNode : public BsdfNode {
523  public:
524   SHADER_NODE_CLASS(AnisotropicBsdfNode)
525 
526   float3 tangent;
527   float roughness, anisotropy, rotation;
528   ClosureType distribution;
529 
get_closure_type()530   ClosureType get_closure_type()
531   {
532     return distribution;
533   }
534   void attributes(Shader *shader, AttributeRequestSet *attributes);
has_attribute_dependency()535   bool has_attribute_dependency()
536   {
537     return true;
538   }
539 };
540 
541 class DiffuseBsdfNode : public BsdfNode {
542  public:
543   SHADER_NODE_CLASS(DiffuseBsdfNode)
544 
545   float roughness;
546 };
547 
548 /* Disney principled BRDF */
549 class PrincipledBsdfNode : public BsdfBaseNode {
550  public:
551   SHADER_NODE_CLASS(PrincipledBsdfNode)
552 
553   void expand(ShaderGraph *graph);
554   bool has_surface_bssrdf();
555   bool has_bssrdf_bump();
556   void compile(SVMCompiler &compiler,
557                ShaderInput *metallic,
558                ShaderInput *subsurface,
559                ShaderInput *subsurface_radius,
560                ShaderInput *specular,
561                ShaderInput *roughness,
562                ShaderInput *specular_tint,
563                ShaderInput *anisotropic,
564                ShaderInput *sheen,
565                ShaderInput *sheen_tint,
566                ShaderInput *clearcoat,
567                ShaderInput *clearcoat_roughness,
568                ShaderInput *ior,
569                ShaderInput *transmission,
570                ShaderInput *anisotropic_rotation,
571                ShaderInput *transmission_roughness);
572 
573   float3 base_color;
574   float3 subsurface_color, subsurface_radius;
575   float metallic, subsurface, specular, roughness, specular_tint, anisotropic, sheen, sheen_tint,
576       clearcoat, clearcoat_roughness, ior, transmission, anisotropic_rotation,
577       transmission_roughness;
578   float3 normal, clearcoat_normal, tangent;
579   float surface_mix_weight;
580   ClosureType distribution, distribution_orig;
581   ClosureType subsurface_method;
582   float3 emission;
583   float emission_strength;
584   float alpha;
585 
586   bool has_integrator_dependency();
587   void attributes(Shader *shader, AttributeRequestSet *attributes);
588   bool has_attribute_dependency()
589   {
590     return true;
591   }
592 };
593 
594 class TranslucentBsdfNode : public BsdfNode {
595  public:
596   SHADER_NODE_CLASS(TranslucentBsdfNode)
597 };
598 
599 class TransparentBsdfNode : public BsdfNode {
600  public:
601   SHADER_NODE_CLASS(TransparentBsdfNode)
602 
603   bool has_surface_transparent()
604   {
605     return true;
606   }
607 };
608 
609 class VelvetBsdfNode : public BsdfNode {
610  public:
611   SHADER_NODE_CLASS(VelvetBsdfNode)
612 
613   float sigma;
614 };
615 
616 class GlossyBsdfNode : public BsdfNode {
617  public:
618   SHADER_NODE_CLASS(GlossyBsdfNode)
619 
620   void simplify_settings(Scene *scene);
621   bool has_integrator_dependency();
622   ClosureType get_closure_type()
623   {
624     return distribution;
625   }
626 
627   float roughness, roughness_orig;
628   ClosureType distribution, distribution_orig;
629 };
630 
631 class GlassBsdfNode : public BsdfNode {
632  public:
633   SHADER_NODE_CLASS(GlassBsdfNode)
634 
635   void simplify_settings(Scene *scene);
636   bool has_integrator_dependency();
637   ClosureType get_closure_type()
638   {
639     return distribution;
640   }
641 
642   float roughness, roughness_orig, IOR;
643   ClosureType distribution, distribution_orig;
644 };
645 
646 class RefractionBsdfNode : public BsdfNode {
647  public:
648   SHADER_NODE_CLASS(RefractionBsdfNode)
649 
650   void simplify_settings(Scene *scene);
651   bool has_integrator_dependency();
652   ClosureType get_closure_type()
653   {
654     return distribution;
655   }
656 
657   float roughness, roughness_orig, IOR;
658   ClosureType distribution, distribution_orig;
659 };
660 
661 class ToonBsdfNode : public BsdfNode {
662  public:
663   SHADER_NODE_CLASS(ToonBsdfNode)
664 
665   float smooth, size;
666   ClosureType component;
667 };
668 
669 class SubsurfaceScatteringNode : public BsdfNode {
670  public:
671   SHADER_NODE_CLASS(SubsurfaceScatteringNode)
672   bool has_surface_bssrdf()
673   {
674     return true;
675   }
676   bool has_bssrdf_bump();
677   ClosureType get_closure_type()
678   {
679     return falloff;
680   }
681 
682   float scale;
683   float3 radius;
684   float sharpness;
685   float texture_blur;
686   ClosureType falloff;
687 };
688 
689 class EmissionNode : public ShaderNode {
690  public:
691   SHADER_NODE_CLASS(EmissionNode)
692   void constant_fold(const ConstantFolder &folder);
693 
694   bool has_surface_emission()
695   {
696     return true;
697   }
698   bool has_volume_support()
699   {
700     return true;
701   }
702 
703   float3 color;
704   float strength;
705   float surface_mix_weight;
706 };
707 
708 class BackgroundNode : public ShaderNode {
709  public:
710   SHADER_NODE_CLASS(BackgroundNode)
711   void constant_fold(const ConstantFolder &folder);
712 
713   float3 color;
714   float strength;
715   float surface_mix_weight;
716 };
717 
718 class HoldoutNode : public ShaderNode {
719  public:
720   SHADER_NODE_CLASS(HoldoutNode)
721   virtual int get_group()
722   {
723     return NODE_GROUP_LEVEL_1;
724   }
725   virtual ClosureType get_closure_type()
726   {
727     return CLOSURE_HOLDOUT_ID;
728   }
729 
730   float surface_mix_weight;
731   float volume_mix_weight;
732 };
733 
734 class AmbientOcclusionNode : public ShaderNode {
735  public:
736   SHADER_NODE_CLASS(AmbientOcclusionNode)
737 
738   bool has_spatial_varying()
739   {
740     return true;
741   }
742   virtual int get_group()
743   {
744     return NODE_GROUP_LEVEL_3;
745   }
746   virtual bool has_raytrace()
747   {
748     return true;
749   }
750 
751   float3 color;
752   float distance;
753   float3 normal;
754   int samples;
755 
756   bool only_local;
757   bool inside;
758 };
759 
760 class VolumeNode : public ShaderNode {
761  public:
762   VolumeNode(const NodeType *node_type);
763   SHADER_NODE_BASE_CLASS(VolumeNode)
764 
765   void compile(SVMCompiler &compiler, ShaderInput *param1, ShaderInput *param2);
766   virtual int get_group()
767   {
768     return NODE_GROUP_LEVEL_1;
769   }
770   virtual int get_feature()
771   {
772     return ShaderNode::get_feature() | NODE_FEATURE_VOLUME;
773   }
774   virtual ClosureType get_closure_type()
775   {
776     return closure;
777   }
778   virtual bool has_volume_support()
779   {
780     return true;
781   }
782 
783   float3 color;
784   float density;
785   float volume_mix_weight;
786   ClosureType closure;
787 
788   virtual bool equals(const ShaderNode & /*other*/)
789   {
790     /* TODO(sergey): With some care Volume nodes can be de-duplicated. */
791     return false;
792   }
793 };
794 
795 class AbsorptionVolumeNode : public VolumeNode {
796  public:
797   SHADER_NODE_CLASS(AbsorptionVolumeNode)
798 };
799 
800 class ScatterVolumeNode : public VolumeNode {
801  public:
802   SHADER_NODE_CLASS(ScatterVolumeNode)
803 
804   float anisotropy;
805 };
806 
807 class PrincipledVolumeNode : public VolumeNode {
808  public:
809   SHADER_NODE_CLASS(PrincipledVolumeNode)
810   void attributes(Shader *shader, AttributeRequestSet *attributes);
811   bool has_attribute_dependency()
812   {
813     return true;
814   }
815 
816   ustring density_attribute;
817   ustring color_attribute;
818   ustring temperature_attribute;
819 
820   float anisotropy;
821   float3 absorption_color;
822   float emission_strength;
823   float3 emission_color;
824   float blackbody_intensity;
825   float3 blackbody_tint;
826   float temperature;
827 };
828 
829 /* Interface between the I/O sockets and the SVM/OSL backend. */
830 class PrincipledHairBsdfNode : public BsdfBaseNode {
831  public:
832   SHADER_NODE_CLASS(PrincipledHairBsdfNode)
833   void attributes(Shader *shader, AttributeRequestSet *attributes);
834 
835   /* Longitudinal roughness. */
836   float roughness;
837   /* Azimuthal roughness. */
838   float radial_roughness;
839   /* Randomization factor for roughnesses. */
840   float random_roughness;
841   /* Longitudinal roughness factor for only the diffuse bounce (shiny undercoat). */
842   float coat;
843   /* Index of reflection. */
844   float ior;
845   /* Cuticle tilt angle. */
846   float offset;
847   /* Direct coloring's color. */
848   float3 color;
849   /* Melanin concentration. */
850   float melanin;
851   /* Melanin redness ratio. */
852   float melanin_redness;
853   /* Dye color. */
854   float3 tint;
855   /* Randomization factor for melanin quantities. */
856   float random_color;
857   /* Absorption coefficient (unfiltered). */
858   float3 absorption_coefficient;
859 
860   float3 normal;
861   float surface_mix_weight;
862   /* If linked, here will be the given random number. */
863   float random;
864   /* Selected coloring parametrization. */
865   NodePrincipledHairParametrization parametrization;
866 };
867 
868 class HairBsdfNode : public BsdfNode {
869  public:
870   SHADER_NODE_CLASS(HairBsdfNode)
871   ClosureType get_closure_type()
872   {
873     return component;
874   }
875 
876   ClosureType component;
877   float offset;
878   float roughness_u;
879   float roughness_v;
880   float3 tangent;
881 };
882 
883 class GeometryNode : public ShaderNode {
884  public:
885   SHADER_NODE_CLASS(GeometryNode)
886   void attributes(Shader *shader, AttributeRequestSet *attributes);
887   bool has_attribute_dependency()
888   {
889     return true;
890   }
891   bool has_spatial_varying()
892   {
893     return true;
894   }
895   int get_group();
896 
897   float3 normal_osl;
898 };
899 
900 class TextureCoordinateNode : public ShaderNode {
901  public:
902   SHADER_NODE_CLASS(TextureCoordinateNode)
903   void attributes(Shader *shader, AttributeRequestSet *attributes);
904   bool has_attribute_dependency()
905   {
906     return true;
907   }
908   bool has_spatial_varying()
909   {
910     return true;
911   }
912 
913   float3 normal_osl;
914   bool from_dupli;
915   bool use_transform;
916   Transform ob_tfm;
917 };
918 
919 class UVMapNode : public ShaderNode {
920  public:
921   SHADER_NODE_CLASS(UVMapNode)
922   void attributes(Shader *shader, AttributeRequestSet *attributes);
923   bool has_attribute_dependency()
924   {
925     return true;
926   }
927   bool has_spatial_varying()
928   {
929     return true;
930   }
931   virtual int get_group()
932   {
933     return NODE_GROUP_LEVEL_1;
934   }
935 
936   ustring attribute;
937   bool from_dupli;
938 };
939 
940 class LightPathNode : public ShaderNode {
941  public:
942   SHADER_NODE_CLASS(LightPathNode)
943   virtual int get_group()
944   {
945     return NODE_GROUP_LEVEL_1;
946   }
947 };
948 
949 class LightFalloffNode : public ShaderNode {
950  public:
951   SHADER_NODE_CLASS(LightFalloffNode)
952   bool has_spatial_varying()
953   {
954     return true;
955   }
956   virtual int get_group()
957   {
958     return NODE_GROUP_LEVEL_2;
959   }
960 
961   float strength;
962   float smooth;
963 };
964 
965 class ObjectInfoNode : public ShaderNode {
966  public:
967   SHADER_NODE_CLASS(ObjectInfoNode)
968   virtual int get_group()
969   {
970     return NODE_GROUP_LEVEL_1;
971   }
972 };
973 
974 class ParticleInfoNode : public ShaderNode {
975  public:
976   SHADER_NODE_CLASS(ParticleInfoNode)
977   void attributes(Shader *shader, AttributeRequestSet *attributes);
978   bool has_attribute_dependency()
979   {
980     return true;
981   }
982   virtual int get_group()
983   {
984     return NODE_GROUP_LEVEL_1;
985   }
986 };
987 
988 class HairInfoNode : public ShaderNode {
989  public:
990   SHADER_NODE_CLASS(HairInfoNode)
991 
992   void attributes(Shader *shader, AttributeRequestSet *attributes);
993   bool has_attribute_dependency()
994   {
995     return true;
996   }
997   bool has_spatial_varying()
998   {
999     return true;
1000   }
1001   virtual int get_group()
1002   {
1003     return NODE_GROUP_LEVEL_1;
1004   }
1005   virtual int get_feature()
1006   {
1007     return ShaderNode::get_feature() | NODE_FEATURE_HAIR;
1008   }
1009 };
1010 
1011 class VolumeInfoNode : public ShaderNode {
1012  public:
1013   SHADER_NODE_CLASS(VolumeInfoNode)
1014   void attributes(Shader *shader, AttributeRequestSet *attributes);
1015   bool has_attribute_dependency()
1016   {
1017     return true;
1018   }
1019   bool has_spatial_varying()
1020   {
1021     return true;
1022   }
1023   void expand(ShaderGraph *graph);
1024 };
1025 
1026 class VertexColorNode : public ShaderNode {
1027  public:
1028   SHADER_NODE_CLASS(VertexColorNode)
1029   void attributes(Shader *shader, AttributeRequestSet *attributes);
1030   bool has_attribute_dependency()
1031   {
1032     return true;
1033   }
1034   bool has_spatial_varying()
1035   {
1036     return true;
1037   }
1038 
1039   ustring layer_name;
1040 };
1041 
1042 class ValueNode : public ShaderNode {
1043  public:
1044   SHADER_NODE_CLASS(ValueNode)
1045 
1046   void constant_fold(const ConstantFolder &folder);
1047 
1048   float value;
1049 };
1050 
1051 class ColorNode : public ShaderNode {
1052  public:
1053   SHADER_NODE_CLASS(ColorNode)
1054 
1055   void constant_fold(const ConstantFolder &folder);
1056 
1057   float3 value;
1058 };
1059 
1060 class AddClosureNode : public ShaderNode {
1061  public:
1062   SHADER_NODE_CLASS(AddClosureNode)
1063   void constant_fold(const ConstantFolder &folder);
1064 };
1065 
1066 class MixClosureNode : public ShaderNode {
1067  public:
1068   SHADER_NODE_CLASS(MixClosureNode)
1069   void constant_fold(const ConstantFolder &folder);
1070 
1071   float fac;
1072 };
1073 
1074 class MixClosureWeightNode : public ShaderNode {
1075  public:
1076   SHADER_NODE_CLASS(MixClosureWeightNode)
1077 
1078   float weight;
1079   float fac;
1080 };
1081 
1082 class InvertNode : public ShaderNode {
1083  public:
1084   SHADER_NODE_CLASS(InvertNode)
1085   void constant_fold(const ConstantFolder &folder);
1086   virtual int get_group()
1087   {
1088     return NODE_GROUP_LEVEL_3;
1089   }
1090 
1091   float fac;
1092   float3 color;
1093 };
1094 
1095 class MixNode : public ShaderNode {
1096  public:
1097   SHADER_NODE_CLASS(MixNode)
1098   void constant_fold(const ConstantFolder &folder);
1099 
1100   virtual int get_group()
1101   {
1102     return NODE_GROUP_LEVEL_3;
1103   }
1104 
1105   NodeMix type;
1106   bool use_clamp;
1107   float3 color1;
1108   float3 color2;
1109   float fac;
1110 };
1111 
1112 class CombineRGBNode : public ShaderNode {
1113  public:
1114   SHADER_NODE_CLASS(CombineRGBNode)
1115   void constant_fold(const ConstantFolder &folder);
1116   virtual int get_group()
1117   {
1118     return NODE_GROUP_LEVEL_3;
1119   }
1120 
1121   float r, g, b;
1122 };
1123 
1124 class CombineHSVNode : public ShaderNode {
1125  public:
1126   SHADER_NODE_CLASS(CombineHSVNode)
1127   void constant_fold(const ConstantFolder &folder);
1128   virtual int get_group()
1129   {
1130     return NODE_GROUP_LEVEL_3;
1131   }
1132 
1133   float h, s, v;
1134 };
1135 
1136 class CombineXYZNode : public ShaderNode {
1137  public:
1138   SHADER_NODE_CLASS(CombineXYZNode)
1139   void constant_fold(const ConstantFolder &folder);
1140   virtual int get_group()
1141   {
1142     return NODE_GROUP_LEVEL_3;
1143   }
1144 
1145   float x, y, z;
1146 };
1147 
1148 class GammaNode : public ShaderNode {
1149  public:
1150   SHADER_NODE_CLASS(GammaNode)
1151   void constant_fold(const ConstantFolder &folder);
1152   virtual int get_group()
1153   {
1154     return NODE_GROUP_LEVEL_1;
1155   }
1156 
1157   float3 color;
1158   float gamma;
1159 };
1160 
1161 class BrightContrastNode : public ShaderNode {
1162  public:
1163   SHADER_NODE_CLASS(BrightContrastNode)
1164   void constant_fold(const ConstantFolder &folder);
1165   virtual int get_group()
1166   {
1167     return NODE_GROUP_LEVEL_1;
1168   }
1169 
1170   float3 color;
1171   float bright;
1172   float contrast;
1173 };
1174 
1175 class SeparateRGBNode : public ShaderNode {
1176  public:
1177   SHADER_NODE_CLASS(SeparateRGBNode)
1178   void constant_fold(const ConstantFolder &folder);
1179   virtual int get_group()
1180   {
1181     return NODE_GROUP_LEVEL_3;
1182   }
1183 
1184   float3 color;
1185 };
1186 
1187 class SeparateHSVNode : public ShaderNode {
1188  public:
1189   SHADER_NODE_CLASS(SeparateHSVNode)
1190   void constant_fold(const ConstantFolder &folder);
1191   virtual int get_group()
1192   {
1193     return NODE_GROUP_LEVEL_3;
1194   }
1195 
1196   float3 color;
1197 };
1198 
1199 class SeparateXYZNode : public ShaderNode {
1200  public:
1201   SHADER_NODE_CLASS(SeparateXYZNode)
1202   void constant_fold(const ConstantFolder &folder);
1203   virtual int get_group()
1204   {
1205     return NODE_GROUP_LEVEL_3;
1206   }
1207 
1208   float3 vector;
1209 };
1210 
1211 class HSVNode : public ShaderNode {
1212  public:
1213   SHADER_NODE_CLASS(HSVNode)
1214 
1215   float hue;
1216   float saturation;
1217   float value;
1218   float fac;
1219   float3 color;
1220 };
1221 
1222 class AttributeNode : public ShaderNode {
1223  public:
1224   SHADER_NODE_CLASS(AttributeNode)
1225   void attributes(Shader *shader, AttributeRequestSet *attributes);
1226   bool has_attribute_dependency()
1227   {
1228     return true;
1229   }
1230   bool has_spatial_varying()
1231   {
1232     return true;
1233   }
1234 
1235   ustring attribute;
1236 };
1237 
1238 class CameraNode : public ShaderNode {
1239  public:
1240   SHADER_NODE_CLASS(CameraNode)
1241   bool has_spatial_varying()
1242   {
1243     return true;
1244   }
1245   virtual int get_group()
1246   {
1247     return NODE_GROUP_LEVEL_2;
1248   }
1249 };
1250 
1251 class FresnelNode : public ShaderNode {
1252  public:
1253   SHADER_NODE_CLASS(FresnelNode)
1254   bool has_spatial_varying()
1255   {
1256     return true;
1257   }
1258   virtual int get_group()
1259   {
1260     return NODE_GROUP_LEVEL_1;
1261   }
1262 
1263   float3 normal;
1264   float IOR;
1265 };
1266 
1267 class LayerWeightNode : public ShaderNode {
1268  public:
1269   SHADER_NODE_CLASS(LayerWeightNode)
1270   bool has_spatial_varying()
1271   {
1272     return true;
1273   }
1274   virtual int get_group()
1275   {
1276     return NODE_GROUP_LEVEL_1;
1277   }
1278 
1279   float3 normal;
1280   float blend;
1281 };
1282 
1283 class WireframeNode : public ShaderNode {
1284  public:
1285   SHADER_NODE_CLASS(WireframeNode)
1286   bool has_spatial_varying()
1287   {
1288     return true;
1289   }
1290   virtual int get_group()
1291   {
1292     return NODE_GROUP_LEVEL_3;
1293   }
1294 
1295   float size;
1296   bool use_pixel_size;
1297 };
1298 
1299 class WavelengthNode : public ShaderNode {
1300  public:
1301   SHADER_NODE_CLASS(WavelengthNode)
1302   virtual int get_group()
1303   {
1304     return NODE_GROUP_LEVEL_3;
1305   }
1306 
1307   float wavelength;
1308 };
1309 
1310 class BlackbodyNode : public ShaderNode {
1311  public:
1312   SHADER_NODE_CLASS(BlackbodyNode)
1313   void constant_fold(const ConstantFolder &folder);
1314   virtual int get_group()
1315   {
1316     return NODE_GROUP_LEVEL_3;
1317   }
1318 
1319   float temperature;
1320 };
1321 
1322 class MapRangeNode : public ShaderNode {
1323  public:
1324   SHADER_NODE_CLASS(MapRangeNode)
1325   virtual int get_group()
1326   {
1327     return NODE_GROUP_LEVEL_3;
1328   }
1329   void expand(ShaderGraph *graph);
1330 
1331   float value, from_min, from_max, to_min, to_max, steps;
1332   NodeMapRangeType type;
1333   bool clamp;
1334 };
1335 
1336 class ClampNode : public ShaderNode {
1337  public:
1338   SHADER_NODE_CLASS(ClampNode)
1339   void constant_fold(const ConstantFolder &folder);
1340   virtual int get_group()
1341   {
1342     return NODE_GROUP_LEVEL_3;
1343   }
1344   float value, min, max;
1345   NodeClampType type;
1346 };
1347 
1348 class MathNode : public ShaderNode {
1349  public:
1350   SHADER_NODE_CLASS(MathNode)
1351   virtual int get_group()
1352   {
1353     return NODE_GROUP_LEVEL_1;
1354   }
1355   void expand(ShaderGraph *graph);
1356   void constant_fold(const ConstantFolder &folder);
1357 
1358   float value1;
1359   float value2;
1360   float value3;
1361   NodeMathType type;
1362   bool use_clamp;
1363 };
1364 
1365 class NormalNode : public ShaderNode {
1366  public:
1367   SHADER_NODE_CLASS(NormalNode)
1368   virtual int get_group()
1369   {
1370     return NODE_GROUP_LEVEL_2;
1371   }
1372 
1373   float3 direction;
1374   float3 normal;
1375 };
1376 
1377 class VectorMathNode : public ShaderNode {
1378  public:
1379   SHADER_NODE_CLASS(VectorMathNode)
1380   virtual int get_group()
1381   {
1382     return NODE_GROUP_LEVEL_1;
1383   }
1384   void constant_fold(const ConstantFolder &folder);
1385 
1386   float3 vector1;
1387   float3 vector2;
1388   float3 vector3;
1389   float scale;
1390   NodeVectorMathType type;
1391 };
1392 
1393 class VectorRotateNode : public ShaderNode {
1394  public:
1395   SHADER_NODE_CLASS(VectorRotateNode)
1396 
1397   virtual int get_group()
1398   {
1399     return NODE_GROUP_LEVEL_3;
1400   }
1401   NodeVectorRotateType type;
1402   bool invert;
1403   float3 vector;
1404   float3 center;
1405   float3 axis;
1406   float angle;
1407   float3 rotation;
1408 };
1409 
1410 class VectorTransformNode : public ShaderNode {
1411  public:
1412   SHADER_NODE_CLASS(VectorTransformNode)
1413 
1414   virtual int get_group()
1415   {
1416     return NODE_GROUP_LEVEL_3;
1417   }
1418 
1419   NodeVectorTransformType type;
1420   NodeVectorTransformConvertSpace convert_from;
1421   NodeVectorTransformConvertSpace convert_to;
1422   float3 vector;
1423 };
1424 
1425 class BumpNode : public ShaderNode {
1426  public:
1427   SHADER_NODE_CLASS(BumpNode)
1428   void constant_fold(const ConstantFolder &folder);
1429   bool has_spatial_varying()
1430   {
1431     return true;
1432   }
1433   virtual int get_feature()
1434   {
1435     return NODE_FEATURE_BUMP;
1436   }
1437 
1438   bool invert;
1439   bool use_object_space;
1440   float height;
1441   float sample_center;
1442   float sample_x;
1443   float sample_y;
1444   float3 normal;
1445   float strength;
1446   float distance;
1447 };
1448 
1449 class CurvesNode : public ShaderNode {
1450  public:
1451   explicit CurvesNode(const NodeType *node_type);
1452   SHADER_NODE_BASE_CLASS(CurvesNode)
1453 
1454   virtual int get_group()
1455   {
1456     return NODE_GROUP_LEVEL_3;
1457   }
1458 
1459   array<float3> curves;
1460   float min_x, max_x, fac;
1461   float3 value;
1462 
1463  protected:
1464   using ShaderNode::constant_fold;
1465   void constant_fold(const ConstantFolder &folder, ShaderInput *value_in);
1466   void compile(SVMCompiler &compiler, int type, ShaderInput *value_in, ShaderOutput *value_out);
1467   void compile(OSLCompiler &compiler, const char *name);
1468 };
1469 
1470 class RGBCurvesNode : public CurvesNode {
1471  public:
1472   SHADER_NODE_CLASS(RGBCurvesNode)
1473   void constant_fold(const ConstantFolder &folder);
1474 };
1475 
1476 class VectorCurvesNode : public CurvesNode {
1477  public:
1478   SHADER_NODE_CLASS(VectorCurvesNode)
1479   void constant_fold(const ConstantFolder &folder);
1480 };
1481 
1482 class RGBRampNode : public ShaderNode {
1483  public:
1484   SHADER_NODE_CLASS(RGBRampNode)
1485   void constant_fold(const ConstantFolder &folder);
1486   virtual int get_group()
1487   {
1488     return NODE_GROUP_LEVEL_1;
1489   }
1490 
1491   array<float3> ramp;
1492   array<float> ramp_alpha;
1493   float fac;
1494   bool interpolate;
1495 };
1496 
1497 class SetNormalNode : public ShaderNode {
1498  public:
1499   SHADER_NODE_CLASS(SetNormalNode)
1500   float3 direction;
1501 };
1502 
1503 class OSLNode : public ShaderNode {
1504  public:
1505   static OSLNode *create(ShaderGraph *graph, size_t num_inputs, const OSLNode *from = NULL);
1506   ~OSLNode();
1507 
1508   ShaderNode *clone(ShaderGraph *graph) const;
1509 
1510   char *input_default_value();
1511   void add_input(ustring name, SocketType::Type type);
1512   void add_output(ustring name, SocketType::Type type);
1513 
1514   SHADER_NODE_NO_CLONE_CLASS(OSLNode)
1515 
1516   /* ideally we could beter detect this, but we can't query this now */
1517   bool has_spatial_varying()
1518   {
1519     return true;
1520   }
1521   bool has_volume_support()
1522   {
1523     return true;
1524   }
1525 
1526   virtual bool equals(const ShaderNode & /*other*/)
1527   {
1528     return false;
1529   }
1530 
1531   string filepath;
1532   string bytecode_hash;
1533 };
1534 
1535 class NormalMapNode : public ShaderNode {
1536  public:
1537   SHADER_NODE_CLASS(NormalMapNode)
1538   void attributes(Shader *shader, AttributeRequestSet *attributes);
1539   bool has_attribute_dependency()
1540   {
1541     return true;
1542   }
1543   bool has_spatial_varying()
1544   {
1545     return true;
1546   }
1547   virtual int get_group()
1548   {
1549     return NODE_GROUP_LEVEL_3;
1550   }
1551 
1552   NodeNormalMapSpace space;
1553   ustring attribute;
1554   float strength;
1555   float3 color;
1556   float3 normal_osl;
1557 };
1558 
1559 class TangentNode : public ShaderNode {
1560  public:
1561   SHADER_NODE_CLASS(TangentNode)
1562   void attributes(Shader *shader, AttributeRequestSet *attributes);
1563   bool has_attribute_dependency()
1564   {
1565     return true;
1566   }
1567   bool has_spatial_varying()
1568   {
1569     return true;
1570   }
1571   virtual int get_group()
1572   {
1573     return NODE_GROUP_LEVEL_3;
1574   }
1575 
1576   NodeTangentDirectionType direction_type;
1577   NodeTangentAxis axis;
1578   ustring attribute;
1579   float3 normal_osl;
1580 };
1581 
1582 class BevelNode : public ShaderNode {
1583  public:
1584   SHADER_NODE_CLASS(BevelNode)
1585   bool has_spatial_varying()
1586   {
1587     return true;
1588   }
1589   virtual int get_group()
1590   {
1591     return NODE_GROUP_LEVEL_3;
1592   }
1593   virtual bool has_raytrace()
1594   {
1595     return true;
1596   }
1597 
1598   float radius;
1599   float3 normal;
1600   int samples;
1601 };
1602 
1603 class DisplacementNode : public ShaderNode {
1604  public:
1605   SHADER_NODE_CLASS(DisplacementNode)
1606   void constant_fold(const ConstantFolder &folder);
1607   virtual int get_feature()
1608   {
1609     return NODE_FEATURE_BUMP;
1610   }
1611 
1612   NodeNormalMapSpace space;
1613   float height;
1614   float midlevel;
1615   float scale;
1616   float3 normal;
1617 };
1618 
1619 class VectorDisplacementNode : public ShaderNode {
1620  public:
1621   SHADER_NODE_CLASS(VectorDisplacementNode)
1622   void attributes(Shader *shader, AttributeRequestSet *attributes);
1623   bool has_attribute_dependency()
1624   {
1625     return true;
1626   }
1627   void constant_fold(const ConstantFolder &folder);
1628   virtual int get_feature()
1629   {
1630     return NODE_FEATURE_BUMP;
1631   }
1632 
1633   NodeNormalMapSpace space;
1634   ustring attribute;
1635   float3 vector;
1636   float midlevel;
1637   float scale;
1638 };
1639 
1640 CCL_NAMESPACE_END
1641 
1642 #endif /* __NODES_H__ */
1643