Cycles: constant folding for RGB/Vector Curves and Color Ramp.
[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 "graph.h"
21 #include "node.h"
22
23 #include "util_string.h"
24
25 CCL_NAMESPACE_BEGIN
26
27 class ImageManager;
28 class Scene;
29 class Shader;
30
31 /* Texture Mapping */
32
33 class TextureMapping {
34 public:
35         TextureMapping();
36         Transform compute_transform();
37         bool skip();
38         void compile(SVMCompiler& compiler, int offset_in, int offset_out);
39         int compile(SVMCompiler& compiler, ShaderInput *vector_in);
40         void compile(OSLCompiler &compiler);
41
42         int compile_begin(SVMCompiler& compiler, ShaderInput *vector_in);
43         void compile_end(SVMCompiler& compiler, ShaderInput *vector_in, int vector_offset);
44
45         float3 translation;
46         float3 rotation;
47         float3 scale;
48
49         float3 min, max;
50         bool use_minmax;
51
52         enum Type { POINT = 0, TEXTURE = 1, VECTOR = 2, NORMAL = 3 };
53         Type type;
54
55         enum Mapping { NONE = 0, X = 1, Y = 2, Z = 3 };
56         Mapping x_mapping, y_mapping, z_mapping;
57
58         enum Projection { FLAT, CUBE, TUBE, SPHERE };
59         Projection projection;
60 };
61
62 /* Nodes */
63
64 class TextureNode : public ShaderNode {
65 public:
66         explicit TextureNode(const NodeType *node_type) : ShaderNode(node_type) {}
67         TextureMapping tex_mapping;
68 };
69
70 /* Any node which uses image manager's slot should be a subclass of this one. */
71 class ImageSlotTextureNode : public TextureNode {
72 public:
73         explicit ImageSlotTextureNode(const NodeType *node_type) : TextureNode(node_type) {
74                 special_type = SHADER_SPECIAL_TYPE_IMAGE_SLOT;
75         }
76         int slot;
77 };
78
79 class ImageTextureNode : public ImageSlotTextureNode {
80 public:
81         SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode)
82         ~ImageTextureNode();
83         ShaderNode *clone() const;
84         void attributes(Shader *shader, AttributeRequestSet *attributes);
85
86         ImageManager *image_manager;
87         int is_float;
88         bool is_linear;
89         bool use_alpha;
90         ustring filename;
91         void *builtin_data;
92         NodeImageColorSpace color_space;
93         NodeImageProjection projection;
94         InterpolationType interpolation;
95         ExtensionType extension;
96         float projection_blend;
97         bool animated;
98         float3 vector;
99
100         virtual bool equals(const ShaderNode& other)
101         {
102                 const ImageTextureNode& image_node = (const ImageTextureNode&)other;
103                 return ImageSlotTextureNode::equals(other) &&
104                        builtin_data == image_node.builtin_data &&
105                        animated == image_node.animated;
106         }
107 };
108
109 class EnvironmentTextureNode : public ImageSlotTextureNode {
110 public:
111         SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode)
112         ~EnvironmentTextureNode();
113         ShaderNode *clone() const;
114         void attributes(Shader *shader, AttributeRequestSet *attributes);
115         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
116
117         ImageManager *image_manager;
118         int is_float;
119         bool is_linear;
120         bool use_alpha;
121         ustring filename;
122         void *builtin_data;
123         NodeImageColorSpace color_space;
124         NodeEnvironmentProjection projection;
125         InterpolationType interpolation;
126         bool animated;
127         float3 vector;
128
129         virtual bool equals(const ShaderNode& other)
130         {
131                 const EnvironmentTextureNode& env_node = (const EnvironmentTextureNode&)other;
132                 return ImageSlotTextureNode::equals(other) &&
133                        builtin_data == env_node.builtin_data &&
134                        animated == env_node.animated;
135         }
136 };
137
138 class SkyTextureNode : public TextureNode {
139 public:
140         SHADER_NODE_CLASS(SkyTextureNode)
141
142         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
143
144         NodeSkyType type;
145         float3 sun_direction;
146         float turbidity;
147         float ground_albedo;
148         float3 vector;
149 };
150
151 class OutputNode : public ShaderNode {
152 public:
153         SHADER_NODE_CLASS(OutputNode)
154
155         void *surface;
156         void *volume;
157         float displacement;
158         float3 normal;
159
160         /* Don't allow output node de-duplication. */
161         virtual bool equals(const ShaderNode& /*other*/) { return false; }
162 };
163
164 class GradientTextureNode : public TextureNode {
165 public:
166         SHADER_NODE_CLASS(GradientTextureNode)
167
168         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
169
170         NodeGradientType type;
171         float3 vector;
172 };
173
174 class NoiseTextureNode : public TextureNode {
175 public:
176         SHADER_NODE_CLASS(NoiseTextureNode)
177
178         float scale, detail, distortion;
179         float3 vector;
180 };
181
182 class VoronoiTextureNode : public TextureNode {
183 public:
184         SHADER_NODE_CLASS(VoronoiTextureNode)
185
186         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
187
188         NodeVoronoiColoring coloring;
189         float scale;
190         float3 vector;
191 };
192
193 class MusgraveTextureNode : public TextureNode {
194 public:
195         SHADER_NODE_CLASS(MusgraveTextureNode)
196
197         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
198
199         NodeMusgraveType type;
200         float scale, detail, dimension, lacunarity, offset, gain;
201         float3 vector;
202 };
203
204 class WaveTextureNode : public TextureNode {
205 public:
206         SHADER_NODE_CLASS(WaveTextureNode)
207
208         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
209
210         NodeWaveType type;
211         NodeWaveProfile profile;
212
213         float scale, distortion, detail, detail_scale;
214         float3 vector;
215 };
216
217 class MagicTextureNode : public TextureNode {
218 public:
219         SHADER_NODE_CLASS(MagicTextureNode)
220
221         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
222
223         int depth;
224         float3 vector;
225         float scale, distortion;
226 };
227
228 class CheckerTextureNode : public TextureNode {
229 public:
230         SHADER_NODE_CLASS(CheckerTextureNode)
231
232         float3 vector, color1, color2;
233         float scale;
234
235         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
236 };
237
238 class BrickTextureNode : public TextureNode {
239 public:
240         SHADER_NODE_CLASS(BrickTextureNode)
241
242         float offset, squash;
243         int offset_frequency, squash_frequency;
244
245         float3 color1, color2, mortar;
246         float scale, mortar_size, bias, brick_width, row_height;
247         float3 vector;
248
249         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
250 };
251
252 class PointDensityTextureNode : public ShaderNode {
253 public:
254         SHADER_NODE_NO_CLONE_CLASS(PointDensityTextureNode)
255
256         ~PointDensityTextureNode();
257         ShaderNode *clone() const;
258         void attributes(Shader *shader, AttributeRequestSet *attributes);
259
260         bool has_spatial_varying() { return true; }
261         bool has_object_dependency() { return true; }
262
263         ustring filename;
264         NodeTexVoxelSpace space;
265         InterpolationType interpolation;
266         Transform tfm;
267         float3 vector;
268
269         ImageManager *image_manager;
270         int slot;
271         void *builtin_data;
272
273         virtual bool equals(const ShaderNode& other) {
274                 const PointDensityTextureNode& point_dendity_node = (const PointDensityTextureNode&)other;
275                 return ShaderNode::equals(other) &&
276                        builtin_data == point_dendity_node.builtin_data;
277         }
278 };
279
280 class MappingNode : public ShaderNode {
281 public:
282         SHADER_NODE_CLASS(MappingNode)
283         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
284
285         float3 vector;
286         TextureMapping tex_mapping;
287 };
288
289 class RGBToBWNode : public ShaderNode {
290 public:
291         SHADER_NODE_CLASS(RGBToBWNode)
292         void constant_fold(const ConstantFolder& folder);
293
294         float3 color;
295 };
296
297 class ConvertNode : public ShaderNode {
298 public:
299         ConvertNode(SocketType::Type from, SocketType::Type to, bool autoconvert = false);
300         SHADER_NODE_BASE_CLASS(ConvertNode)
301
302         void constant_fold(const ConstantFolder& folder);
303
304         SocketType::Type from, to;
305
306         union {
307                 float value_float;
308                 int value_int;
309                 float3 value_color;
310                 float3 value_vector;
311                 float3 value_point;
312                 float3 value_normal;
313         };
314         ustring value_string;
315
316 private:
317         static const int MAX_TYPE = 12;
318         static bool register_types();
319         static Node* create(const NodeType *type);
320         static const NodeType *node_types[MAX_TYPE][MAX_TYPE];
321         static bool initialized;
322 };
323
324 class BsdfNode : public ShaderNode {
325 public:
326         explicit BsdfNode(const NodeType *node_type);
327         SHADER_NODE_BASE_CLASS(BsdfNode);
328
329         bool has_spatial_varying() { return true; }
330         void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL, ShaderInput *param4 = NULL);
331         virtual ClosureType get_closure_type() { return closure; }
332
333         float3 color;
334         float3 normal;
335         float surface_mix_weight;
336         ClosureType closure;
337
338         virtual bool equals(const ShaderNode& /*other*/)
339         {
340                 /* TODO(sergey): With some care BSDF nodes can be de-duplicated. */
341                 return false;
342         }
343 };
344
345 class AnisotropicBsdfNode : public BsdfNode {
346 public:
347         SHADER_NODE_CLASS(AnisotropicBsdfNode)
348
349         float3 tangent;
350         float roughness, anisotropy, rotation;
351         ClosureType distribution;
352
353         ClosureType get_closure_type() { return distribution; }
354         void attributes(Shader *shader, AttributeRequestSet *attributes);
355 };
356
357 class DiffuseBsdfNode : public BsdfNode {
358 public:
359         SHADER_NODE_CLASS(DiffuseBsdfNode)
360
361         float roughness;
362 };
363
364 class TranslucentBsdfNode : public BsdfNode {
365 public:
366         SHADER_NODE_CLASS(TranslucentBsdfNode)
367 };
368
369 class TransparentBsdfNode : public BsdfNode {
370 public:
371         SHADER_NODE_CLASS(TransparentBsdfNode)
372
373         bool has_surface_transparent() { return true; }
374 };
375
376 class VelvetBsdfNode : public BsdfNode {
377 public:
378         SHADER_NODE_CLASS(VelvetBsdfNode)
379
380         float sigma;
381 };
382
383 class GlossyBsdfNode : public BsdfNode {
384 public:
385         SHADER_NODE_CLASS(GlossyBsdfNode)
386
387         void simplify_settings(Scene *scene);
388         bool has_integrator_dependency();
389         ClosureType get_closure_type() { return distribution; }
390
391         float roughness;
392         ClosureType distribution, distribution_orig;
393 };
394
395 class GlassBsdfNode : public BsdfNode {
396 public:
397         SHADER_NODE_CLASS(GlassBsdfNode)
398
399         void simplify_settings(Scene *scene);
400         bool has_integrator_dependency();
401         ClosureType get_closure_type() { return distribution; }
402
403         float roughness, IOR;
404         ClosureType distribution, distribution_orig;
405 };
406
407 class RefractionBsdfNode : public BsdfNode {
408 public:
409         SHADER_NODE_CLASS(RefractionBsdfNode)
410
411         void simplify_settings(Scene *scene);
412         bool has_integrator_dependency();
413         ClosureType get_closure_type() { return distribution; }
414
415         float roughness, IOR;
416         ClosureType distribution, distribution_orig;
417 };
418
419 class ToonBsdfNode : public BsdfNode {
420 public:
421         SHADER_NODE_CLASS(ToonBsdfNode)
422
423         float smooth, size;
424         ClosureType component;
425 };
426
427 class SubsurfaceScatteringNode : public BsdfNode {
428 public:
429         SHADER_NODE_CLASS(SubsurfaceScatteringNode)
430         bool has_surface_bssrdf() { return true; }
431         bool has_bssrdf_bump();
432         ClosureType get_closure_type() { return falloff; }
433
434         float scale;
435         float3 radius;
436         float sharpness;
437         float texture_blur;
438         ClosureType falloff;
439 };
440
441 class EmissionNode : public ShaderNode {
442 public:
443         SHADER_NODE_CLASS(EmissionNode)
444         void constant_fold(const ConstantFolder& folder);
445         virtual ClosureType get_closure_type() { return CLOSURE_EMISSION_ID; }
446
447         bool has_surface_emission() { return true; }
448
449         float3 color;
450         float strength;
451         float surface_mix_weight;
452 };
453
454 class BackgroundNode : public ShaderNode {
455 public:
456         SHADER_NODE_CLASS(BackgroundNode)
457         void constant_fold(const ConstantFolder& folder);
458         virtual ClosureType get_closure_type() { return CLOSURE_BACKGROUND_ID; }
459
460         float3 color;
461         float strength;
462         float surface_mix_weight;
463 };
464
465 class HoldoutNode : public ShaderNode {
466 public:
467         SHADER_NODE_CLASS(HoldoutNode)
468         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
469         virtual ClosureType get_closure_type() { return CLOSURE_HOLDOUT_ID; }
470
471         float surface_mix_weight;
472         float volume_mix_weight;
473 };
474
475 class AmbientOcclusionNode : public ShaderNode {
476 public:
477         SHADER_NODE_CLASS(AmbientOcclusionNode)
478
479         bool has_spatial_varying() { return true; }
480         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
481         virtual ClosureType get_closure_type() { return CLOSURE_AMBIENT_OCCLUSION_ID; }
482
483         float3 normal_osl;
484         float3 color;
485         float surface_mix_weight;
486 };
487
488 class VolumeNode : public ShaderNode {
489 public:
490         VolumeNode(const NodeType *node_type);
491         SHADER_NODE_BASE_CLASS(VolumeNode)
492
493         void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2);
494         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
495         virtual int get_feature() {
496                 return ShaderNode::get_feature() | NODE_FEATURE_VOLUME;
497         }
498         virtual ClosureType get_closure_type() { return closure; }
499
500         float3 color;
501         float density;
502         float volume_mix_weight;
503         ClosureType closure;
504
505         virtual bool equals(const ShaderNode& /*other*/)
506         {
507                 /* TODO(sergey): With some care Volume nodes can be de-duplicated. */
508                 return false;
509         }
510 };
511
512 class AbsorptionVolumeNode : public VolumeNode {
513 public:
514         SHADER_NODE_CLASS(AbsorptionVolumeNode)
515 };
516
517 class ScatterVolumeNode : public VolumeNode {
518 public:
519         SHADER_NODE_CLASS(ScatterVolumeNode)
520
521         float anisotropy;
522 };
523
524 class HairBsdfNode : public BsdfNode {
525 public:
526         SHADER_NODE_CLASS(HairBsdfNode)
527         ClosureType get_closure_type() { return component; }
528
529         ClosureType component;
530         float offset;
531         float roughness_u;
532         float roughness_v;
533         float3 tangent;
534 };
535
536 class GeometryNode : public ShaderNode {
537 public:
538         SHADER_NODE_CLASS(GeometryNode)
539         void attributes(Shader *shader, AttributeRequestSet *attributes);
540         bool has_spatial_varying() { return true; }
541
542         float3 normal_osl;
543 };
544
545 class TextureCoordinateNode : public ShaderNode {
546 public:
547         SHADER_NODE_CLASS(TextureCoordinateNode)
548         void attributes(Shader *shader, AttributeRequestSet *attributes);
549         bool has_spatial_varying() { return true; }
550         bool has_object_dependency() { return use_transform; }
551
552         float3 normal_osl;
553         bool from_dupli;
554         bool use_transform;
555         Transform ob_tfm;
556 };
557
558 class UVMapNode : public ShaderNode {
559 public:
560         SHADER_NODE_CLASS(UVMapNode)
561         void attributes(Shader *shader, AttributeRequestSet *attributes);
562         bool has_spatial_varying() { return true; }
563         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
564
565         ustring attribute;
566         bool from_dupli;
567 };
568
569 class LightPathNode : public ShaderNode {
570 public:
571         SHADER_NODE_CLASS(LightPathNode)
572         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
573 };
574
575 class LightFalloffNode : public ShaderNode {
576 public:
577         SHADER_NODE_CLASS(LightFalloffNode)
578         bool has_spatial_varying() { return true; }
579         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
580
581         float strength;
582         float smooth;
583 };
584
585 class ObjectInfoNode : public ShaderNode {
586 public:
587         SHADER_NODE_CLASS(ObjectInfoNode)
588         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
589 };
590
591 class ParticleInfoNode : public ShaderNode {
592 public:
593         SHADER_NODE_CLASS(ParticleInfoNode)
594         void attributes(Shader *shader, AttributeRequestSet *attributes);
595         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
596 };
597
598 class HairInfoNode : public ShaderNode {
599 public:
600         SHADER_NODE_CLASS(HairInfoNode)
601
602         void attributes(Shader *shader, AttributeRequestSet *attributes);
603         bool has_spatial_varying() { return true; }
604         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
605         virtual int get_feature() {
606                 return ShaderNode::get_feature() | NODE_FEATURE_HAIR;
607         }
608 };
609
610 class ValueNode : public ShaderNode {
611 public:
612         SHADER_NODE_CLASS(ValueNode)
613
614         void constant_fold(const ConstantFolder& folder);
615
616         float value;
617 };
618
619 class ColorNode : public ShaderNode {
620 public:
621         SHADER_NODE_CLASS(ColorNode)
622
623         void constant_fold(const ConstantFolder& folder);
624
625         float3 value;
626 };
627
628 class AddClosureNode : public ShaderNode {
629 public:
630         SHADER_NODE_CLASS(AddClosureNode)
631         void constant_fold(const ConstantFolder& folder);
632 };
633
634 class MixClosureNode : public ShaderNode {
635 public:
636         SHADER_NODE_CLASS(MixClosureNode)
637         void constant_fold(const ConstantFolder& folder);
638
639         float fac;
640 };
641
642 class MixClosureWeightNode : public ShaderNode {
643 public:
644         SHADER_NODE_CLASS(MixClosureWeightNode);
645
646         float weight;
647         float fac;
648 };
649
650 class InvertNode : public ShaderNode {
651 public:
652         SHADER_NODE_CLASS(InvertNode)
653         void constant_fold(const ConstantFolder& folder);
654         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
655
656         float fac;
657         float3 color;
658 };
659
660 class MixNode : public ShaderNode {
661 public:
662         SHADER_NODE_CLASS(MixNode)
663         void constant_fold(const ConstantFolder& folder);
664
665         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
666
667         NodeMix type;
668         bool use_clamp;
669         float3 color1;
670         float3 color2;
671         float fac;
672 };
673
674 class CombineRGBNode : public ShaderNode {
675 public:
676         SHADER_NODE_CLASS(CombineRGBNode)
677         void constant_fold(const ConstantFolder& folder);
678         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
679
680         float r, g, b;
681 };
682
683 class CombineHSVNode : public ShaderNode {
684 public:
685         SHADER_NODE_CLASS(CombineHSVNode)
686         void constant_fold(const ConstantFolder& folder);
687         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
688
689         float h, s, v;
690 };
691
692 class CombineXYZNode : public ShaderNode {
693 public:
694         SHADER_NODE_CLASS(CombineXYZNode)
695         void constant_fold(const ConstantFolder& folder);
696         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
697
698         float x, y, z;
699 };
700
701 class GammaNode : public ShaderNode {
702 public:
703         SHADER_NODE_CLASS(GammaNode)
704         void constant_fold(const ConstantFolder& folder);
705         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
706
707         float3 color;
708         float gamma;
709 };
710
711 class BrightContrastNode : public ShaderNode {
712 public:
713         SHADER_NODE_CLASS(BrightContrastNode)
714         void constant_fold(const ConstantFolder& folder);
715         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
716
717         float3 color;
718         float bright;
719         float contrast;
720 };
721
722 class SeparateRGBNode : public ShaderNode {
723 public:
724         SHADER_NODE_CLASS(SeparateRGBNode)
725         void constant_fold(const ConstantFolder& folder);
726         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
727
728         float3 color;
729 };
730
731 class SeparateHSVNode : public ShaderNode {
732 public:
733         SHADER_NODE_CLASS(SeparateHSVNode)
734         void constant_fold(const ConstantFolder& folder);
735         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
736
737         float3 color;
738 };
739
740 class SeparateXYZNode : public ShaderNode {
741 public:
742         SHADER_NODE_CLASS(SeparateXYZNode)
743         void constant_fold(const ConstantFolder& folder);
744         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
745
746         float3 vector;
747 };
748
749 class HSVNode : public ShaderNode {
750 public:
751         SHADER_NODE_CLASS(HSVNode)
752
753         float hue;
754         float saturation;
755         float value;
756         float fac;
757         float3 color;
758 };
759
760 class AttributeNode : public ShaderNode {
761 public:
762         SHADER_NODE_CLASS(AttributeNode)
763         void attributes(Shader *shader, AttributeRequestSet *attributes);
764         bool has_spatial_varying() { return true; }
765
766         ustring attribute;
767 };
768
769 class CameraNode : public ShaderNode {
770 public:
771         SHADER_NODE_CLASS(CameraNode)
772         bool has_spatial_varying() { return true; }
773 };
774
775 class FresnelNode : public ShaderNode {
776 public:
777         SHADER_NODE_CLASS(FresnelNode)
778         bool has_spatial_varying() { return true; }
779         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
780
781         float3 normal;
782         float IOR;
783 };
784
785 class LayerWeightNode : public ShaderNode {
786 public:
787         SHADER_NODE_CLASS(LayerWeightNode)
788         bool has_spatial_varying() { return true; }
789         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
790
791         float3 normal;
792         float blend;
793 };
794
795 class WireframeNode : public ShaderNode {
796 public:
797         SHADER_NODE_CLASS(WireframeNode)
798         bool has_spatial_varying() { return true; }
799         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
800
801         float size;
802         bool use_pixel_size;
803 };
804
805 class WavelengthNode : public ShaderNode {
806 public:
807         SHADER_NODE_CLASS(WavelengthNode)
808         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
809
810         float wavelength;
811 };
812
813 class BlackbodyNode : public ShaderNode {
814 public:
815         SHADER_NODE_CLASS(BlackbodyNode)
816         void constant_fold(const ConstantFolder& folder);
817         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
818
819         float temperature;
820 };
821
822 class MathNode : public ShaderNode {
823 public:
824         SHADER_NODE_CLASS(MathNode)
825         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
826         void constant_fold(const ConstantFolder& folder);
827
828         float value1;
829         float value2;
830         NodeMath type;
831         bool use_clamp;
832 };
833
834 class NormalNode : public ShaderNode {
835 public:
836         SHADER_NODE_CLASS(NormalNode)
837         virtual int get_group() { return NODE_GROUP_LEVEL_2; }
838
839         float3 direction;
840         float3 normal;
841 };
842
843 class VectorMathNode : public ShaderNode {
844 public:
845         SHADER_NODE_CLASS(VectorMathNode)
846         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
847         void constant_fold(const ConstantFolder& folder);
848
849         float3 vector1;
850         float3 vector2;
851         NodeVectorMath type;
852 };
853
854 class VectorTransformNode : public ShaderNode {
855 public:
856         SHADER_NODE_CLASS(VectorTransformNode)
857
858         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
859
860         NodeVectorTransformType type;
861         NodeVectorTransformConvertSpace convert_from;
862         NodeVectorTransformConvertSpace convert_to;
863         float3 vector;
864 };
865
866 class BumpNode : public ShaderNode {
867 public:
868         SHADER_NODE_CLASS(BumpNode)
869         void constant_fold(const ConstantFolder& folder);
870         bool has_spatial_varying() { return true; }
871         virtual int get_feature() {
872                 return NODE_FEATURE_BUMP;
873         }
874
875         bool invert;
876         float height;
877         float sample_center;
878         float sample_x;
879         float sample_y;
880         float3 normal;
881         float strength;
882         float distance;
883 };
884
885 class CurvesNode : public ShaderNode {
886 public:
887         explicit CurvesNode(const NodeType *node_type);
888         SHADER_NODE_BASE_CLASS(CurvesNode);
889
890         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
891
892         array<float3> curves;
893         float min_x, max_x, fac;
894         float3 value;
895
896 protected:
897         void constant_fold(const ConstantFolder& folder, ShaderInput *value_in);
898         void compile(SVMCompiler& compiler, int type, ShaderInput *value_in, ShaderOutput *value_out);
899         void compile(OSLCompiler& compiler, const char *name);
900 };
901
902 class RGBCurvesNode : public CurvesNode {
903 public:
904         SHADER_NODE_CLASS(RGBCurvesNode)
905         void constant_fold(const ConstantFolder& folder);
906 };
907
908 class VectorCurvesNode : public CurvesNode {
909 public:
910         SHADER_NODE_CLASS(VectorCurvesNode)
911         void constant_fold(const ConstantFolder& folder);
912 };
913
914 class RGBRampNode : public ShaderNode {
915 public:
916         SHADER_NODE_CLASS(RGBRampNode)
917         void constant_fold(const ConstantFolder& folder);
918         virtual int get_group() { return NODE_GROUP_LEVEL_1; }
919
920         array<float3> ramp;
921         array<float> ramp_alpha;
922         float fac;
923         bool interpolate;
924 };
925
926 class SetNormalNode : public ShaderNode {
927 public:
928         SHADER_NODE_CLASS(SetNormalNode)
929         float3 direction;
930 };
931
932 class OSLNode : public ShaderNode {
933 public:
934         static OSLNode *create(size_t num_inputs, const OSLNode *from = NULL);
935         ~OSLNode();
936
937         ShaderNode *clone() const;
938
939         char* input_default_value();
940         void add_input(ustring name, SocketType::Type type);
941         void add_output(ustring name, SocketType::Type type);
942
943         SHADER_NODE_NO_CLONE_CLASS(OSLNode)
944
945         /* ideally we could beter detect this, but we can't query this now */
946         bool has_spatial_varying() { return true; }
947         virtual bool equals(const ShaderNode& /*other*/) { return false; }
948
949         string filepath;
950         string bytecode_hash;
951 };
952
953 class NormalMapNode : public ShaderNode {
954 public:
955         SHADER_NODE_CLASS(NormalMapNode)
956         void attributes(Shader *shader, AttributeRequestSet *attributes);
957         bool has_spatial_varying() { return true; }
958         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
959
960         NodeNormalMapSpace space;
961         ustring attribute;
962         float strength;
963         float3 color;
964         float3 normal_osl;
965 };
966
967 class TangentNode : public ShaderNode {
968 public:
969         SHADER_NODE_CLASS(TangentNode)
970         void attributes(Shader *shader, AttributeRequestSet *attributes);
971         bool has_spatial_varying() { return true; }
972         virtual int get_group() { return NODE_GROUP_LEVEL_3; }
973
974         NodeTangentDirectionType direction_type;
975         NodeTangentAxis axis;
976         ustring attribute;
977         float3 normal_osl;
978 };
979
980 CCL_NAMESPACE_END
981
982 #endif /* __NODES_H__ */
983