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