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