Cycles: Add support for single channel float textures on CPU.
[blender.git] / intern / cycles / render / nodes.cpp
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "image.h"
18 #include "integrator.h"
19 #include "nodes.h"
20 #include "scene.h"
21 #include "svm.h"
22 #include "svm_math_util.h"
23 #include "osl.h"
24
25 #include "util_sky_model.h"
26 #include "util_foreach.h"
27 #include "util_transform.h"
28
29 CCL_NAMESPACE_BEGIN
30
31 /* Texture Mapping */
32
33 TextureMapping::TextureMapping()
34 {
35         translation = make_float3(0.0f, 0.0f, 0.0f);
36         rotation = make_float3(0.0f, 0.0f, 0.0f);
37         scale = make_float3(1.0f, 1.0f, 1.0f);
38
39         min = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
40         max = make_float3(FLT_MAX, FLT_MAX, FLT_MAX);
41
42         use_minmax = false;
43
44         x_mapping = X;
45         y_mapping = Y;
46         z_mapping = Z;
47
48         type = TEXTURE;
49
50         projection = FLAT;
51 }
52
53 Transform TextureMapping::compute_transform()
54 {
55         Transform mmat = transform_scale(make_float3(0.0f, 0.0f, 0.0f));
56
57         if(x_mapping != NONE)
58                 mmat[0][x_mapping-1] = 1.0f;
59         if(y_mapping != NONE)
60                 mmat[1][y_mapping-1] = 1.0f;
61         if(z_mapping != NONE)
62                 mmat[2][z_mapping-1] = 1.0f;
63         
64         float3 scale_clamped = scale;
65
66         if(type == TEXTURE || type == NORMAL) {
67                 /* keep matrix invertible */
68                 if(fabsf(scale.x) < 1e-5f)
69                         scale_clamped.x = signf(scale.x)*1e-5f;
70                 if(fabsf(scale.y) < 1e-5f)
71                         scale_clamped.y = signf(scale.y)*1e-5f;
72                 if(fabsf(scale.z) < 1e-5f)
73                         scale_clamped.z = signf(scale.z)*1e-5f;
74         }
75         
76         Transform smat = transform_scale(scale_clamped);
77         Transform rmat = transform_euler(rotation);
78         Transform tmat = transform_translate(translation);
79
80         Transform mat;
81
82         switch(type) {
83                 case TEXTURE:
84                         /* inverse transform on texture coordinate gives
85                          * forward transform on texture */
86                         mat = tmat*rmat*smat;
87                         mat = transform_inverse(mat);
88                         break;
89                 case POINT:
90                         /* full transform */
91                         mat = tmat*rmat*smat;
92                         break;
93                 case VECTOR:
94                         /* no translation for vectors */
95                         mat = rmat*smat;
96                         break;
97                 case NORMAL:
98                         /* no translation for normals, and inverse transpose */
99                         mat = rmat*smat;
100                         mat = transform_inverse(mat);
101                         mat = transform_transpose(mat);
102                         break;
103         }
104
105         /* projection last */
106         mat = mat*mmat;
107
108         return mat;
109 }
110
111 bool TextureMapping::skip()
112 {
113         if(translation != make_float3(0.0f, 0.0f, 0.0f))
114                 return false;
115         if(rotation != make_float3(0.0f, 0.0f, 0.0f))
116                 return false;
117         if(scale != make_float3(1.0f, 1.0f, 1.0f))
118                 return false;
119         
120         if(x_mapping != X || y_mapping != Y || z_mapping != Z)
121                 return false;
122         if(use_minmax)
123                 return false;
124         
125         return true;
126 }
127
128 void TextureMapping::compile(SVMCompiler& compiler, int offset_in, int offset_out)
129 {
130         compiler.add_node(NODE_MAPPING, offset_in, offset_out);
131
132         Transform tfm = compute_transform();
133         compiler.add_node(tfm.x);
134         compiler.add_node(tfm.y);
135         compiler.add_node(tfm.z);
136         compiler.add_node(tfm.w);
137
138         if(use_minmax) {
139                 compiler.add_node(NODE_MIN_MAX, offset_out, offset_out);
140                 compiler.add_node(float3_to_float4(min));
141                 compiler.add_node(float3_to_float4(max));
142         }
143
144         if(type == NORMAL) {
145                 compiler.add_node(NODE_VECTOR_MATH, NODE_VECTOR_MATH_NORMALIZE, offset_out, offset_out);
146                 compiler.add_node(NODE_VECTOR_MATH, SVM_STACK_INVALID, offset_out);
147         }
148 }
149
150 /* Convenience function for texture nodes, allocating stack space to output
151  * a modified vector and returning its offset */
152 int TextureMapping::compile_begin(SVMCompiler& compiler, ShaderInput *vector_in)
153 {
154         if(!skip()) {
155                 int offset_in = compiler.stack_assign(vector_in);
156                 int offset_out = compiler.stack_find_offset(SHADER_SOCKET_VECTOR);
157
158                 compile(compiler, offset_in, offset_out);
159
160                 return offset_out;
161         }
162
163         return compiler.stack_assign(vector_in);
164 }
165
166 void TextureMapping::compile_end(SVMCompiler& compiler, ShaderInput *vector_in, int vector_offset)
167 {
168         if(!skip()) {
169                 compiler.stack_clear_offset(vector_in->type, vector_offset);
170         }
171 }
172
173 void TextureMapping::compile(OSLCompiler &compiler)
174 {
175         if(!skip()) {
176                 Transform tfm = transform_transpose(compute_transform());
177
178                 compiler.parameter("mapping", tfm);
179                 compiler.parameter("use_mapping", 1);
180         }
181 }
182
183 /* Image Texture */
184
185 static ShaderEnum color_space_init()
186 {
187         ShaderEnum enm;
188
189         enm.insert("None", 0);
190         enm.insert("Color", 1);
191
192         return enm;
193 }
194
195 static ShaderEnum image_projection_init()
196 {
197         ShaderEnum enm;
198
199         enm.insert("Flat", NODE_IMAGE_PROJ_FLAT);
200         enm.insert("Box", NODE_IMAGE_PROJ_BOX);
201         enm.insert("Sphere", NODE_IMAGE_PROJ_SPHERE);
202         enm.insert("Tube", NODE_IMAGE_PROJ_TUBE);
203
204         return enm;
205 }
206
207 static const char* get_osl_interpolation_parameter(InterpolationType interpolation)
208 {
209         switch(interpolation) {
210                 case INTERPOLATION_CLOSEST:
211                         return "closest";
212                 case INTERPOLATION_CUBIC:
213                         return "cubic";
214                 case INTERPOLATION_SMART:
215                         return "smart";
216                 case INTERPOLATION_LINEAR:
217                 default:
218                         return "linear";
219         }
220 }
221
222 ShaderEnum ImageTextureNode::color_space_enum = color_space_init();
223 ShaderEnum ImageTextureNode::projection_enum = image_projection_init();
224
225 ImageTextureNode::ImageTextureNode()
226 : ImageSlotTextureNode("image_texture")
227 {
228         image_manager = NULL;
229         slot = -1;
230         is_float = -1;
231         is_linear = false;
232         use_alpha = true;
233         filename = "";
234         builtin_data = NULL;
235         color_space = ustring("Color");
236         projection = ustring("Flat");
237         interpolation = INTERPOLATION_LINEAR;
238         extension = EXTENSION_REPEAT;
239         projection_blend = 0.0f;
240         animated = false;
241
242         add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_UV);
243         add_output("Color", SHADER_SOCKET_COLOR);
244         add_output("Alpha", SHADER_SOCKET_FLOAT);
245 }
246
247 ImageTextureNode::~ImageTextureNode()
248 {
249         if(image_manager) {
250                 image_manager->remove_image(filename,
251                                             builtin_data,
252                                             interpolation,
253                                             extension);
254         }
255 }
256
257 ShaderNode *ImageTextureNode::clone() const
258 {
259         ImageTextureNode *node = new ImageTextureNode(*this);
260         node->image_manager = NULL;
261         node->slot = -1;
262         node->is_float = -1;
263         node->is_linear = false;
264         return node;
265 }
266
267 void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
268 {
269 #ifdef WITH_PTEX
270         /* todo: avoid loading other texture coordinates when using ptex,
271          * and hide texture coordinate socket in the UI */
272         if(shader->has_surface && string_endswith(filename, ".ptx")) {
273                 /* ptex */
274                 attributes->add(ATTR_STD_PTEX_FACE_ID);
275                 attributes->add(ATTR_STD_PTEX_UV);
276         }
277 #endif
278
279         ShaderNode::attributes(shader, attributes);
280 }
281
282 void ImageTextureNode::compile(SVMCompiler& compiler)
283 {
284         ShaderInput *vector_in = input("Vector");
285         ShaderOutput *color_out = output("Color");
286         ShaderOutput *alpha_out = output("Alpha");
287
288         image_manager = compiler.image_manager;
289         if(is_float == -1) {
290                 bool is_float_bool;
291                 slot = image_manager->add_image(filename,
292                                                 builtin_data,
293                                                 animated,
294                                                 0,
295                                                 is_float_bool,
296                                                 is_linear,
297                                                 interpolation,
298                                                 extension,
299                                                 use_alpha);
300                 is_float = (int)is_float_bool;
301         }
302
303         if(slot != -1) {
304                 int srgb = (is_linear || color_space != "Color")? 0: 1;
305                 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
306
307                 if(projection != "Box") {
308                         compiler.add_node(NODE_TEX_IMAGE,
309                                 slot,
310                                 compiler.encode_uchar4(
311                                         vector_offset,
312                                         compiler.stack_assign_if_linked(color_out),
313                                         compiler.stack_assign_if_linked(alpha_out),
314                                         srgb),
315                                 projection_enum[projection]);
316                 }
317                 else {
318                         compiler.add_node(NODE_TEX_IMAGE_BOX,
319                                 slot,
320                                 compiler.encode_uchar4(
321                                         vector_offset,
322                                         compiler.stack_assign_if_linked(color_out),
323                                         compiler.stack_assign_if_linked(alpha_out),
324                                         srgb),
325                                 __float_as_int(projection_blend));
326                 }
327
328                 tex_mapping.compile_end(compiler, vector_in, vector_offset);
329         }
330         else {
331                 /* image not found */
332                 if(!color_out->links.empty()) {
333                         compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
334                         compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R,
335                                                                     TEX_IMAGE_MISSING_G,
336                                                                     TEX_IMAGE_MISSING_B));
337                 }
338                 if(!alpha_out->links.empty())
339                         compiler.add_node(NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), compiler.stack_assign(alpha_out));
340         }
341 }
342
343 void ImageTextureNode::compile(OSLCompiler& compiler)
344 {
345         ShaderOutput *alpha_out = output("Alpha");
346
347         tex_mapping.compile(compiler);
348
349         image_manager = compiler.image_manager;
350         if(is_float == -1) {
351                 if(builtin_data == NULL) {
352                         ImageManager::ImageDataType type;
353                         type = image_manager->get_image_metadata(filename, NULL, is_linear);
354                         if(type == ImageManager::IMAGE_DATA_TYPE_FLOAT || type == ImageManager::IMAGE_DATA_TYPE_FLOAT4)
355                                 is_float = 1;
356                 }
357                 else {
358                         bool is_float_bool;
359                         slot = image_manager->add_image(filename,
360                                                         builtin_data,
361                                                         animated,
362                                                         0,
363                                                         is_float_bool,
364                                                         is_linear,
365                                                         interpolation,
366                                                         extension,
367                                                         use_alpha);
368                         is_float = (int)is_float_bool;
369                 }
370         }
371
372         if(slot == -1) {
373                 compiler.parameter("filename", filename.c_str());
374         }
375         else {
376                 /* TODO(sergey): It's not so simple to pass custom attribute
377                  * to the texture() function in order to make builtin images
378                  * support more clear. So we use special file name which is
379                  * "@<slot_number>" and check whether file name matches this
380                  * mask in the OSLRenderServices::texture().
381                  */
382                 compiler.parameter("filename", string_printf("@%d", slot).c_str());
383         }
384         if(is_linear || color_space != "Color")
385                 compiler.parameter("color_space", "Linear");
386         else
387                 compiler.parameter("color_space", "sRGB");
388         compiler.parameter("projection", projection);
389         compiler.parameter("projection_blend", projection_blend);
390         compiler.parameter("is_float", is_float);
391         compiler.parameter("use_alpha", !alpha_out->links.empty());
392         compiler.parameter("interpolation", get_osl_interpolation_parameter(interpolation));
393
394         switch(extension) {
395                 case EXTENSION_EXTEND:
396                         compiler.parameter("wrap", "clamp");
397                         break;
398                 case EXTENSION_CLIP:
399                         compiler.parameter("wrap", "black");
400                         break;
401                 case EXTENSION_REPEAT:
402                 default:
403                         compiler.parameter("wrap", "periodic");
404                         break;
405         }
406
407         compiler.add(this, "node_image_texture");
408 }
409
410 /* Environment Texture */
411
412 static ShaderEnum env_projection_init()
413 {
414         ShaderEnum enm;
415
416         enm.insert("Equirectangular", 0);
417         enm.insert("Mirror Ball", 1);
418
419         return enm;
420 }
421
422 ShaderEnum EnvironmentTextureNode::color_space_enum = color_space_init();
423 ShaderEnum EnvironmentTextureNode::projection_enum = env_projection_init();
424
425 EnvironmentTextureNode::EnvironmentTextureNode()
426 : ImageSlotTextureNode("environment_texture")
427 {
428         image_manager = NULL;
429         slot = -1;
430         is_float = -1;
431         is_linear = false;
432         use_alpha = true;
433         filename = "";
434         builtin_data = NULL;
435         color_space = ustring("Color");
436         interpolation = INTERPOLATION_LINEAR;
437         projection = ustring("Equirectangular");
438         animated = false;
439
440         add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION);
441         add_output("Color", SHADER_SOCKET_COLOR);
442         add_output("Alpha", SHADER_SOCKET_FLOAT);
443 }
444
445 EnvironmentTextureNode::~EnvironmentTextureNode()
446 {
447         if(image_manager) {
448                 image_manager->remove_image(filename,
449                                             builtin_data,
450                                             interpolation,
451                                             EXTENSION_REPEAT);
452         }
453 }
454
455 ShaderNode *EnvironmentTextureNode::clone() const
456 {
457         EnvironmentTextureNode *node = new EnvironmentTextureNode(*this);
458         node->image_manager = NULL;
459         node->slot = -1;
460         node->is_float = -1;
461         node->is_linear = false;
462         return node;
463 }
464
465 void EnvironmentTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
466 {
467 #ifdef WITH_PTEX
468         if(shader->has_surface && string_endswith(filename, ".ptx")) {
469                 /* ptex */
470                 attributes->add(ATTR_STD_PTEX_FACE_ID);
471                 attributes->add(ATTR_STD_PTEX_UV);
472         }
473 #endif
474
475         ShaderNode::attributes(shader, attributes);
476 }
477
478 void EnvironmentTextureNode::compile(SVMCompiler& compiler)
479 {
480         ShaderInput *vector_in = input("Vector");
481         ShaderOutput *color_out = output("Color");
482         ShaderOutput *alpha_out = output("Alpha");
483
484         image_manager = compiler.image_manager;
485         if(slot == -1) {
486                 bool is_float_bool;
487                 slot = image_manager->add_image(filename,
488                                                 builtin_data,
489                                                 animated,
490                                                 0,
491                                                 is_float_bool,
492                                                 is_linear,
493                                                 interpolation,
494                                                 EXTENSION_REPEAT,
495                                                 use_alpha);
496                 is_float = (int)is_float_bool;
497         }
498
499         if(slot != -1) {
500                 int srgb = (is_linear || color_space != "Color")? 0: 1;
501                 int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
502
503                 compiler.add_node(NODE_TEX_ENVIRONMENT,
504                         slot,
505                         compiler.encode_uchar4(
506                                 vector_offset,
507                                 compiler.stack_assign_if_linked(color_out),
508                                 compiler.stack_assign_if_linked(alpha_out),
509                                 srgb),
510                         projection_enum[projection]);
511         
512                 tex_mapping.compile_end(compiler, vector_in, vector_offset);
513         }
514         else {
515                 /* image not found */
516                 if(!color_out->links.empty()) {
517                         compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
518                         compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R,
519                                                                     TEX_IMAGE_MISSING_G,
520                                                                     TEX_IMAGE_MISSING_B));
521                 }
522                 if(!alpha_out->links.empty())
523                         compiler.add_node(NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), compiler.stack_assign(alpha_out));
524         }
525 }
526
527 void EnvironmentTextureNode::compile(OSLCompiler& compiler)
528 {
529         ShaderOutput *alpha_out = output("Alpha");
530
531         tex_mapping.compile(compiler);
532
533         /* See comments in ImageTextureNode::compile about support
534          * of builtin images.
535          */
536         image_manager = compiler.image_manager;
537         if(is_float == -1) {
538                 if(builtin_data == NULL) {
539                         ImageManager::ImageDataType type;
540                         type = image_manager->get_image_metadata(filename, NULL, is_linear);
541                         if(type == ImageManager::IMAGE_DATA_TYPE_FLOAT || type == ImageManager::IMAGE_DATA_TYPE_FLOAT4)
542                                 is_float = 1;
543                 }
544                 else {
545                         bool is_float_bool;
546                         slot = image_manager->add_image(filename,
547                                                         builtin_data,
548                                                         animated,
549                                                         0,
550                                                         is_float_bool,
551                                                         is_linear,
552                                                         interpolation,
553                                                         EXTENSION_REPEAT,
554                                                         use_alpha);
555                         is_float = (int)is_float_bool;
556                 }
557         }
558
559         if(slot == -1) {
560                 compiler.parameter("filename", filename.c_str());
561         }
562         else {
563                 compiler.parameter("filename", string_printf("@%d", slot).c_str());
564         }
565         compiler.parameter("projection", projection);
566         if(is_linear || color_space != "Color")
567                 compiler.parameter("color_space", "Linear");
568         else
569                 compiler.parameter("color_space", "sRGB");
570
571         compiler.parameter("interpolation", get_osl_interpolation_parameter(interpolation));
572
573         compiler.parameter("is_float", is_float);
574         compiler.parameter("use_alpha", !alpha_out->links.empty());
575         compiler.add(this, "node_environment_texture");
576 }
577
578 /* Sky Texture */
579
580 static float2 sky_spherical_coordinates(float3 dir)
581 {
582         return make_float2(acosf(dir.z), atan2f(dir.x, dir.y));
583 }
584
585 typedef struct SunSky {
586         /* sun direction in spherical and cartesian */
587         float theta, phi;
588
589         /* Parameter */
590         float radiance_x, radiance_y, radiance_z;
591         float config_x[9], config_y[9], config_z[9];
592 } SunSky;
593
594 /* Preetham model */
595 static float sky_perez_function(float lam[6], float theta, float gamma)
596 {
597         return (1.0f + lam[0]*expf(lam[1]/cosf(theta))) * (1.0f + lam[2]*expf(lam[3]*gamma)  + lam[4]*cosf(gamma)*cosf(gamma));
598 }
599
600 static void sky_texture_precompute_old(SunSky *sunsky, float3 dir, float turbidity)
601 {
602         /*
603         * We re-use the SunSky struct of the new model, to avoid extra variables
604         * zenith_Y/x/y is now radiance_x/y/z
605         * perez_Y/x/y is now config_x/y/z
606         */
607         
608         float2 spherical = sky_spherical_coordinates(dir);
609         float theta = spherical.x;
610         float phi = spherical.y;
611
612         sunsky->theta = theta;
613         sunsky->phi = phi;
614
615         float theta2 = theta*theta;
616         float theta3 = theta2*theta;
617         float T = turbidity;
618         float T2 = T * T;
619
620         float chi = (4.0f / 9.0f - T / 120.0f) * (M_PI_F - 2.0f * theta);
621         sunsky->radiance_x = (4.0453f * T - 4.9710f) * tanf(chi) - 0.2155f * T + 2.4192f;
622         sunsky->radiance_x *= 0.06f;
623
624         sunsky->radiance_y =
625         (0.00166f * theta3 - 0.00375f * theta2 + 0.00209f * theta) * T2 +
626         (-0.02903f * theta3 + 0.06377f * theta2 - 0.03202f * theta + 0.00394f) * T +
627         (0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * theta + 0.25886f);
628
629         sunsky->radiance_z =
630         (0.00275f * theta3 - 0.00610f * theta2 + 0.00317f * theta) * T2 +
631         (-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * theta  + 0.00516f) * T +
632         (0.15346f * theta3 - 0.26756f * theta2 + 0.06670f * theta  + 0.26688f);
633
634         sunsky->config_x[0] = (0.1787f * T  - 1.4630f);
635         sunsky->config_x[1] = (-0.3554f * T  + 0.4275f);
636         sunsky->config_x[2] = (-0.0227f * T  + 5.3251f);
637         sunsky->config_x[3] = (0.1206f * T  - 2.5771f);
638         sunsky->config_x[4] = (-0.0670f * T  + 0.3703f);
639
640         sunsky->config_y[0] = (-0.0193f * T  - 0.2592f);
641         sunsky->config_y[1] = (-0.0665f * T  + 0.0008f);
642         sunsky->config_y[2] = (-0.0004f * T  + 0.2125f);
643         sunsky->config_y[3] = (-0.0641f * T  - 0.8989f);
644         sunsky->config_y[4] = (-0.0033f * T  + 0.0452f);
645
646         sunsky->config_z[0] = (-0.0167f * T  - 0.2608f);
647         sunsky->config_z[1] = (-0.0950f * T  + 0.0092f);
648         sunsky->config_z[2] = (-0.0079f * T  + 0.2102f);
649         sunsky->config_z[3] = (-0.0441f * T  - 1.6537f);
650         sunsky->config_z[4] = (-0.0109f * T  + 0.0529f);
651
652         /* unused for old sky model */
653         for(int i = 5; i < 9; i++) {
654                 sunsky->config_x[i] = 0.0f;
655                 sunsky->config_y[i] = 0.0f;
656                 sunsky->config_z[i] = 0.0f;
657         }
658
659         sunsky->radiance_x /= sky_perez_function(sunsky->config_x, 0, theta);
660         sunsky->radiance_y /= sky_perez_function(sunsky->config_y, 0, theta);
661         sunsky->radiance_z /= sky_perez_function(sunsky->config_z, 0, theta);
662 }
663
664 /* Hosek / Wilkie */
665 static void sky_texture_precompute_new(SunSky *sunsky, float3 dir, float turbidity, float ground_albedo)
666 {
667         /* Calculate Sun Direction and save coordinates */
668         float2 spherical = sky_spherical_coordinates(dir);
669         float theta = spherical.x;
670         float phi = spherical.y;
671         
672         /* Clamp Turbidity */
673         turbidity = clamp(turbidity, 0.0f, 10.0f); 
674         
675         /* Clamp to Horizon */
676         theta = clamp(theta, 0.0f, M_PI_2_F); 
677
678         sunsky->theta = theta;
679         sunsky->phi = phi;
680
681         double solarElevation = M_PI_2_F - theta;
682
683         /* Initialize Sky Model */
684         ArHosekSkyModelState *sky_state;
685         sky_state = arhosek_xyz_skymodelstate_alloc_init(turbidity, ground_albedo, solarElevation);
686
687         /* Copy values from sky_state to SunSky */
688         for(int i = 0; i < 9; ++i) {
689                 sunsky->config_x[i] = (float)sky_state->configs[0][i];
690                 sunsky->config_y[i] = (float)sky_state->configs[1][i];
691                 sunsky->config_z[i] = (float)sky_state->configs[2][i];
692         }
693         sunsky->radiance_x = (float)sky_state->radiances[0];
694         sunsky->radiance_y = (float)sky_state->radiances[1];
695         sunsky->radiance_z = (float)sky_state->radiances[2];
696
697         /* Free sky_state */
698         arhosekskymodelstate_free(sky_state);
699 }
700
701 static ShaderEnum sky_type_init()
702 {
703         ShaderEnum enm;
704
705         enm.insert("Preetham", NODE_SKY_OLD);
706         enm.insert("Hosek / Wilkie", NODE_SKY_NEW);
707
708         return enm;
709 }
710
711 ShaderEnum SkyTextureNode::type_enum = sky_type_init();
712
713 SkyTextureNode::SkyTextureNode()
714 : TextureNode("sky_texture")
715 {
716         type = ustring("Hosek / Wilkie");
717         
718         sun_direction = make_float3(0.0f, 0.0f, 1.0f);
719         turbidity = 2.2f;
720         ground_albedo = 0.3f;
721
722         add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION);
723         add_output("Color", SHADER_SOCKET_COLOR);
724 }
725
726 void SkyTextureNode::compile(SVMCompiler& compiler)
727 {
728         ShaderInput *vector_in = input("Vector");
729         ShaderOutput *color_out = output("Color");
730
731         SunSky sunsky;
732         if(type_enum[type] == NODE_SKY_OLD)
733                 sky_texture_precompute_old(&sunsky, sun_direction, turbidity);
734         else if(type_enum[type] == NODE_SKY_NEW)
735                 sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo);
736         else
737                 assert(false);
738
739         int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
740         int sky_model = type_enum[type];
741
742         compiler.stack_assign(color_out);
743         compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), sky_model);
744         compiler.add_node(__float_as_uint(sunsky.phi), __float_as_uint(sunsky.theta), __float_as_uint(sunsky.radiance_x), __float_as_uint(sunsky.radiance_y));
745         compiler.add_node(__float_as_uint(sunsky.radiance_z), __float_as_uint(sunsky.config_x[0]), __float_as_uint(sunsky.config_x[1]), __float_as_uint(sunsky.config_x[2]));
746         compiler.add_node(__float_as_uint(sunsky.config_x[3]), __float_as_uint(sunsky.config_x[4]), __float_as_uint(sunsky.config_x[5]), __float_as_uint(sunsky.config_x[6]));
747         compiler.add_node(__float_as_uint(sunsky.config_x[7]), __float_as_uint(sunsky.config_x[8]), __float_as_uint(sunsky.config_y[0]), __float_as_uint(sunsky.config_y[1]));
748         compiler.add_node(__float_as_uint(sunsky.config_y[2]), __float_as_uint(sunsky.config_y[3]), __float_as_uint(sunsky.config_y[4]), __float_as_uint(sunsky.config_y[5]));
749         compiler.add_node(__float_as_uint(sunsky.config_y[6]), __float_as_uint(sunsky.config_y[7]), __float_as_uint(sunsky.config_y[8]), __float_as_uint(sunsky.config_z[0]));
750         compiler.add_node(__float_as_uint(sunsky.config_z[1]), __float_as_uint(sunsky.config_z[2]), __float_as_uint(sunsky.config_z[3]), __float_as_uint(sunsky.config_z[4]));
751         compiler.add_node(__float_as_uint(sunsky.config_z[5]), __float_as_uint(sunsky.config_z[6]), __float_as_uint(sunsky.config_z[7]), __float_as_uint(sunsky.config_z[8]));
752
753         tex_mapping.compile_end(compiler, vector_in, vector_offset);
754 }
755
756 void SkyTextureNode::compile(OSLCompiler& compiler)
757 {
758         tex_mapping.compile(compiler);
759
760         SunSky sunsky;
761
762         if(type_enum[type] == NODE_SKY_OLD)
763                 sky_texture_precompute_old(&sunsky, sun_direction, turbidity);
764         else if(type_enum[type] == NODE_SKY_NEW)
765                 sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo);
766         else
767                 assert(false);
768                 
769         compiler.parameter("sky_model", type);
770         compiler.parameter("theta", sunsky.theta);
771         compiler.parameter("phi", sunsky.phi);
772         compiler.parameter_color("radiance", make_float3(sunsky.radiance_x, sunsky.radiance_y, sunsky.radiance_z));
773         compiler.parameter_array("config_x", sunsky.config_x, 9);
774         compiler.parameter_array("config_y", sunsky.config_y, 9);
775         compiler.parameter_array("config_z", sunsky.config_z, 9);
776         compiler.add(this, "node_sky_texture");
777 }
778
779 /* Gradient Texture */
780
781 static ShaderEnum gradient_type_init()
782 {
783         ShaderEnum enm;
784
785         enm.insert("Linear", NODE_BLEND_LINEAR);
786         enm.insert("Quadratic", NODE_BLEND_QUADRATIC);
787         enm.insert("Easing", NODE_BLEND_EASING);
788         enm.insert("Diagonal", NODE_BLEND_DIAGONAL);
789         enm.insert("Radial", NODE_BLEND_RADIAL);
790         enm.insert("Quadratic Sphere", NODE_BLEND_QUADRATIC_SPHERE);
791         enm.insert("Spherical", NODE_BLEND_SPHERICAL);
792
793         return enm;
794 }
795
796 ShaderEnum GradientTextureNode::type_enum = gradient_type_init();
797
798 GradientTextureNode::GradientTextureNode()
799 : TextureNode("gradient_texture")
800 {
801         type = ustring("Linear");
802
803         add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
804         add_output("Color", SHADER_SOCKET_COLOR);
805         add_output("Fac", SHADER_SOCKET_FLOAT);
806 }
807
808 void GradientTextureNode::compile(SVMCompiler& compiler)
809 {
810         ShaderInput *vector_in = input("Vector");
811         ShaderOutput *color_out = output("Color");
812         ShaderOutput *fac_out = output("Fac");
813
814         int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
815
816         compiler.add_node(NODE_TEX_GRADIENT,
817                 compiler.encode_uchar4(
818                         type_enum[type],
819                         vector_offset,
820                         compiler.stack_assign_if_linked(fac_out),
821                         compiler.stack_assign_if_linked(color_out)));
822
823         tex_mapping.compile_end(compiler, vector_in, vector_offset);
824 }
825
826 void GradientTextureNode::compile(OSLCompiler& compiler)
827 {
828         tex_mapping.compile(compiler);
829
830         compiler.parameter("Type", type);
831         compiler.add(this, "node_gradient_texture");
832 }
833
834 /* Noise Texture */
835
836 NoiseTextureNode::NoiseTextureNode()
837 : TextureNode("noise_texture")
838 {
839         add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
840         add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f);
841         add_input("Detail", SHADER_SOCKET_FLOAT, 2.0f);
842         add_input("Distortion", SHADER_SOCKET_FLOAT, 0.0f);
843
844         add_output("Color", SHADER_SOCKET_COLOR);
845         add_output("Fac", SHADER_SOCKET_FLOAT);
846 }
847
848 void NoiseTextureNode::compile(SVMCompiler& compiler)
849 {
850         ShaderInput *distortion_in = input("Distortion");
851         ShaderInput *detail_in = input("Detail");
852         ShaderInput *scale_in = input("Scale");
853         ShaderInput *vector_in = input("Vector");
854         ShaderOutput *color_out = output("Color");
855         ShaderOutput *fac_out = output("Fac");
856
857         int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
858
859         compiler.add_node(NODE_TEX_NOISE,
860                 compiler.encode_uchar4(
861                         vector_offset,
862                         compiler.stack_assign_if_linked(scale_in),
863                         compiler.stack_assign_if_linked(detail_in),
864                         compiler.stack_assign_if_linked(distortion_in)),
865                 compiler.encode_uchar4(
866                         compiler.stack_assign_if_linked(color_out),
867                         compiler.stack_assign_if_linked(fac_out)));
868         compiler.add_node(
869                 __float_as_int(scale_in->value.x),
870                 __float_as_int(detail_in->value.x),
871                 __float_as_int(distortion_in->value.x));
872
873         tex_mapping.compile_end(compiler, vector_in, vector_offset);
874 }
875
876 void NoiseTextureNode::compile(OSLCompiler& compiler)
877 {
878         tex_mapping.compile(compiler);
879
880         compiler.add(this, "node_noise_texture");
881 }
882
883 /* Voronoi Texture */
884
885 static ShaderEnum voronoi_coloring_init()
886 {
887         ShaderEnum enm;
888
889         enm.insert("Intensity", NODE_VORONOI_INTENSITY);
890         enm.insert("Cells", NODE_VORONOI_CELLS);
891
892         return enm;
893 }
894
895 ShaderEnum VoronoiTextureNode::coloring_enum  = voronoi_coloring_init();
896
897 VoronoiTextureNode::VoronoiTextureNode()
898 : TextureNode("voronoi_texture")
899 {
900         coloring = ustring("Intensity");
901
902         add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f);
903         add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
904
905         add_output("Color", SHADER_SOCKET_COLOR);
906         add_output("Fac", SHADER_SOCKET_FLOAT);
907 }
908
909 void VoronoiTextureNode::compile(SVMCompiler& compiler)
910 {
911         ShaderInput *scale_in = input("Scale");
912         ShaderInput *vector_in = input("Vector");
913         ShaderOutput *color_out = output("Color");
914         ShaderOutput *fac_out = output("Fac");
915
916         int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
917
918         compiler.add_node(NODE_TEX_VORONOI,
919                 coloring_enum[coloring],
920                 compiler.encode_uchar4(
921                         compiler.stack_assign_if_linked(scale_in),
922                         vector_offset,
923                         compiler.stack_assign(fac_out),
924                         compiler.stack_assign(color_out)),
925                 __float_as_int(scale_in->value.x));
926
927         tex_mapping.compile_end(compiler, vector_in, vector_offset);
928 }
929
930 void VoronoiTextureNode::compile(OSLCompiler& compiler)
931 {
932         tex_mapping.compile(compiler);
933
934         compiler.parameter("Coloring", coloring);
935         compiler.add(this, "node_voronoi_texture");
936 }
937
938 /* Musgrave Texture */
939
940 static ShaderEnum musgrave_type_init()
941 {
942         ShaderEnum enm;
943
944         enm.insert("Multifractal", NODE_MUSGRAVE_MULTIFRACTAL);
945         enm.insert("fBM", NODE_MUSGRAVE_FBM);
946         enm.insert("Hybrid Multifractal", NODE_MUSGRAVE_HYBRID_MULTIFRACTAL);
947         enm.insert("Ridged Multifractal", NODE_MUSGRAVE_RIDGED_MULTIFRACTAL);
948         enm.insert("Hetero Terrain", NODE_MUSGRAVE_HETERO_TERRAIN);
949
950         return enm;
951 }
952
953 ShaderEnum MusgraveTextureNode::type_enum = musgrave_type_init();
954
955 MusgraveTextureNode::MusgraveTextureNode()
956 : TextureNode("musgrave_texture")
957 {
958         type = ustring("fBM");
959
960         add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f);
961         add_input("Detail", SHADER_SOCKET_FLOAT, 2.0f);
962         add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
963         add_input("Dimension", SHADER_SOCKET_FLOAT, 2.0f);
964         add_input("Lacunarity", SHADER_SOCKET_FLOAT, 1.0f);
965         add_input("Offset", SHADER_SOCKET_FLOAT, 0.0f);
966         add_input("Gain", SHADER_SOCKET_FLOAT, 1.0f);
967
968         add_output("Fac", SHADER_SOCKET_FLOAT);
969         add_output("Color", SHADER_SOCKET_COLOR);
970 }
971
972 void MusgraveTextureNode::compile(SVMCompiler& compiler)
973 {
974         ShaderInput *vector_in = input("Vector");
975         ShaderInput *scale_in = input("Scale");
976         ShaderInput *dimension_in = input("Dimension");
977         ShaderInput *lacunarity_in = input("Lacunarity");
978         ShaderInput *detail_in = input("Detail");
979         ShaderInput *offset_in = input("Offset");
980         ShaderInput *gain_in = input("Gain");
981         ShaderOutput *fac_out = output("Fac");
982         ShaderOutput *color_out = output("Color");
983
984         int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
985
986         compiler.add_node(NODE_TEX_MUSGRAVE,
987                 compiler.encode_uchar4(
988                         type_enum[type],
989                         vector_offset,
990                         compiler.stack_assign_if_linked(color_out),
991                         compiler.stack_assign_if_linked(fac_out)),
992                 compiler.encode_uchar4(
993                         compiler.stack_assign_if_linked(dimension_in),
994                         compiler.stack_assign_if_linked(lacunarity_in),
995                         compiler.stack_assign_if_linked(detail_in),
996                         compiler.stack_assign_if_linked(offset_in)),
997                 compiler.encode_uchar4(
998                         compiler.stack_assign_if_linked(gain_in),
999                         compiler.stack_assign_if_linked(scale_in)));
1000         compiler.add_node(__float_as_int(dimension_in->value.x),
1001                 __float_as_int(lacunarity_in->value.x),
1002                 __float_as_int(detail_in->value.x),
1003                 __float_as_int(offset_in->value.x));
1004         compiler.add_node(__float_as_int(gain_in->value.x),
1005                 __float_as_int(scale_in->value.x));
1006
1007         tex_mapping.compile_end(compiler, vector_in, vector_offset);
1008 }
1009
1010 void MusgraveTextureNode::compile(OSLCompiler& compiler)
1011 {
1012         tex_mapping.compile(compiler);
1013
1014         compiler.parameter("Type", type);
1015
1016         compiler.add(this, "node_musgrave_texture");
1017 }
1018
1019 /* Wave Texture */
1020
1021 static ShaderEnum wave_type_init()
1022 {
1023         ShaderEnum enm;
1024
1025         enm.insert("Bands", NODE_WAVE_BANDS);
1026         enm.insert("Rings", NODE_WAVE_RINGS);
1027
1028         return enm;
1029 }
1030
1031 static ShaderEnum wave_profile_init()
1032 {
1033         ShaderEnum enm;
1034
1035         enm.insert("Sine", NODE_WAVE_PROFILE_SIN);
1036         enm.insert("Saw", NODE_WAVE_PROFILE_SAW);
1037
1038         return enm;
1039 }
1040
1041 ShaderEnum WaveTextureNode::type_enum = wave_type_init();
1042 ShaderEnum WaveTextureNode::profile_enum = wave_profile_init();
1043
1044 WaveTextureNode::WaveTextureNode()
1045 : TextureNode("wave_texture")
1046 {
1047         type = ustring("Bands");
1048         profile = ustring("Sine");
1049
1050         add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f);
1051         add_input("Distortion", SHADER_SOCKET_FLOAT, 0.0f);
1052         add_input("Detail", SHADER_SOCKET_FLOAT, 2.0f);
1053         add_input("Detail Scale", SHADER_SOCKET_FLOAT, 1.0f);
1054         add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
1055
1056         add_output("Color", SHADER_SOCKET_COLOR);
1057         add_output("Fac", SHADER_SOCKET_FLOAT);
1058 }
1059
1060 void WaveTextureNode::compile(SVMCompiler& compiler)
1061 {
1062         ShaderInput *scale_in = input("Scale");
1063         ShaderInput *distortion_in = input("Distortion");
1064         ShaderInput *dscale_in = input("Detail Scale");
1065         ShaderInput *detail_in = input("Detail");
1066         ShaderInput *vector_in = input("Vector");
1067         ShaderOutput *fac_out = output("Fac");
1068         ShaderOutput *color_out = output("Color");
1069
1070         int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1071
1072         compiler.add_node(NODE_TEX_WAVE,
1073                 compiler.encode_uchar4(
1074                         type_enum[type],
1075                         compiler.stack_assign_if_linked(color_out),
1076                         compiler.stack_assign_if_linked(fac_out),
1077                         compiler.stack_assign_if_linked(dscale_in)),
1078                 compiler.encode_uchar4(
1079                         vector_offset,
1080                         compiler.stack_assign_if_linked(scale_in),
1081                         compiler.stack_assign_if_linked(detail_in),
1082                         compiler.stack_assign_if_linked(distortion_in)),
1083                 profile_enum[profile]);
1084
1085         compiler.add_node(
1086                 __float_as_int(scale_in->value.x),
1087                 __float_as_int(detail_in->value.x),
1088                 __float_as_int(distortion_in->value.x),
1089                 __float_as_int(dscale_in->value.x));
1090
1091         tex_mapping.compile_end(compiler, vector_in, vector_offset);
1092 }
1093
1094 void WaveTextureNode::compile(OSLCompiler& compiler)
1095 {
1096         tex_mapping.compile(compiler);
1097
1098         compiler.parameter("Type", type);
1099         compiler.parameter("Profile", profile);
1100
1101         compiler.add(this, "node_wave_texture");
1102 }
1103
1104 /* Magic Texture */
1105
1106 MagicTextureNode::MagicTextureNode()
1107 : TextureNode("magic_texture")
1108 {
1109         depth = 2;
1110
1111         add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
1112         add_input("Scale", SHADER_SOCKET_FLOAT, 5.0f);
1113         add_input("Distortion", SHADER_SOCKET_FLOAT, 1.0f);
1114
1115         add_output("Color", SHADER_SOCKET_COLOR);
1116         add_output("Fac", SHADER_SOCKET_FLOAT);
1117 }
1118
1119 void MagicTextureNode::compile(SVMCompiler& compiler)
1120 {
1121         ShaderInput *vector_in = input("Vector");
1122         ShaderInput *scale_in = input("Scale");
1123         ShaderInput *distortion_in = input("Distortion");
1124         ShaderOutput *color_out = output("Color");
1125         ShaderOutput *fac_out = output("Fac");
1126
1127         int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1128
1129         compiler.add_node(NODE_TEX_MAGIC,
1130                 compiler.encode_uchar4(
1131                         depth,
1132                         compiler.stack_assign_if_linked(color_out),
1133                         compiler.stack_assign_if_linked(fac_out)),
1134                 compiler.encode_uchar4(
1135                         vector_offset,
1136                         compiler.stack_assign_if_linked(scale_in),
1137                         compiler.stack_assign_if_linked(distortion_in)));
1138         compiler.add_node(
1139                 __float_as_int(scale_in->value.x),
1140                 __float_as_int(distortion_in->value.x));
1141
1142         tex_mapping.compile_end(compiler, vector_in, vector_offset);
1143 }
1144
1145 void MagicTextureNode::compile(OSLCompiler& compiler)
1146 {
1147         tex_mapping.compile(compiler);
1148
1149         compiler.parameter("Depth", depth);
1150         compiler.add(this, "node_magic_texture");
1151 }
1152
1153 /* Checker Texture */
1154
1155 CheckerTextureNode::CheckerTextureNode()
1156 : TextureNode("checker_texture")
1157 {
1158         add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
1159         add_input("Color1", SHADER_SOCKET_COLOR);
1160         add_input("Color2", SHADER_SOCKET_COLOR);
1161         add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f);
1162
1163         add_output("Color", SHADER_SOCKET_COLOR);
1164         add_output("Fac", SHADER_SOCKET_FLOAT);
1165 }
1166
1167 void CheckerTextureNode::compile(SVMCompiler& compiler)
1168 {
1169         ShaderInput *vector_in = input("Vector");
1170         ShaderInput *color1_in = input("Color1");
1171         ShaderInput *color2_in = input("Color2");
1172         ShaderInput *scale_in = input("Scale");
1173         
1174         ShaderOutput *color_out = output("Color");
1175         ShaderOutput *fac_out = output("Fac");
1176
1177         int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1178
1179         compiler.add_node(NODE_TEX_CHECKER,
1180                 compiler.encode_uchar4(
1181                         vector_offset,
1182                         compiler.stack_assign(color1_in),
1183                         compiler.stack_assign(color2_in),
1184                         compiler.stack_assign_if_linked(scale_in)),
1185                 compiler.encode_uchar4(
1186                         compiler.stack_assign_if_linked(color_out),
1187                         compiler.stack_assign_if_linked(fac_out)),
1188                 __float_as_int(scale_in->value.x));
1189
1190         tex_mapping.compile_end(compiler, vector_in, vector_offset);
1191 }
1192
1193 void CheckerTextureNode::compile(OSLCompiler& compiler)
1194 {
1195         tex_mapping.compile(compiler);
1196
1197         compiler.add(this, "node_checker_texture");
1198 }
1199
1200 /* Brick Texture */
1201
1202 BrickTextureNode::BrickTextureNode()
1203 : TextureNode("brick_texture")
1204 {
1205         offset = 0.5f;
1206         offset_frequency = 2;
1207         squash = 1.0f;
1208         squash_frequency = 2;
1209         
1210         add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
1211         add_input("Color1", SHADER_SOCKET_COLOR);
1212         add_input("Color2", SHADER_SOCKET_COLOR);
1213         add_input("Mortar", SHADER_SOCKET_COLOR);
1214         add_input("Scale", SHADER_SOCKET_FLOAT, 5.0f);
1215         add_input("Mortar Size", SHADER_SOCKET_FLOAT, 0.02f);
1216         add_input("Bias", SHADER_SOCKET_FLOAT, 0.0f);
1217         add_input("Brick Width", SHADER_SOCKET_FLOAT, 0.5f);
1218         add_input("Row Height", SHADER_SOCKET_FLOAT, 0.25f);
1219
1220         add_output("Color", SHADER_SOCKET_COLOR);
1221         add_output("Fac", SHADER_SOCKET_FLOAT);
1222 }
1223
1224 void BrickTextureNode::compile(SVMCompiler& compiler)
1225 {
1226         ShaderInput *vector_in = input("Vector");
1227         ShaderInput *color1_in = input("Color1");
1228         ShaderInput *color2_in = input("Color2");
1229         ShaderInput *mortar_in = input("Mortar");
1230         ShaderInput *scale_in = input("Scale");
1231         ShaderInput *mortar_size_in = input("Mortar Size");
1232         ShaderInput *bias_in = input("Bias");
1233         ShaderInput *brick_width_in = input("Brick Width");
1234         ShaderInput *row_height_in = input("Row Height");
1235         
1236         ShaderOutput *color_out = output("Color");
1237         ShaderOutput *fac_out = output("Fac");
1238
1239         int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
1240
1241         compiler.add_node(NODE_TEX_BRICK,
1242                 compiler.encode_uchar4(
1243                         vector_offset,
1244                         compiler.stack_assign(color1_in),
1245                         compiler.stack_assign(color2_in),
1246                         compiler.stack_assign(mortar_in)),
1247                 compiler.encode_uchar4(
1248                         compiler.stack_assign_if_linked(scale_in),
1249                         compiler.stack_assign_if_linked(mortar_size_in),
1250                         compiler.stack_assign_if_linked(bias_in),
1251                         compiler.stack_assign_if_linked(brick_width_in)),
1252                 compiler.encode_uchar4(
1253                         compiler.stack_assign_if_linked(row_height_in),
1254                         compiler.stack_assign_if_linked(color_out),
1255                         compiler.stack_assign_if_linked(fac_out)));
1256                         
1257         compiler.add_node(compiler.encode_uchar4(offset_frequency, squash_frequency),
1258                 __float_as_int(scale_in->value.x),
1259                 __float_as_int(mortar_size_in->value.x),
1260                 __float_as_int(bias_in->value.x));
1261
1262         compiler.add_node(__float_as_int(brick_width_in->value.x),
1263                 __float_as_int(row_height_in->value.x),
1264                 __float_as_int(offset),
1265                 __float_as_int(squash));
1266
1267         tex_mapping.compile_end(compiler, vector_in, vector_offset);
1268 }
1269
1270 void BrickTextureNode::compile(OSLCompiler& compiler)
1271 {
1272         tex_mapping.compile(compiler);
1273
1274         compiler.parameter("Offset", offset);
1275         compiler.parameter("OffsetFrequency", offset_frequency);
1276         compiler.parameter("Squash", squash);
1277         compiler.parameter("SquashFrequency", squash_frequency);
1278         compiler.add(this, "node_brick_texture");
1279 }
1280
1281 /* Point Density Texture */
1282
1283 static ShaderEnum point_density_space_init()
1284 {
1285         ShaderEnum enm;
1286
1287         enm.insert("Object", NODE_TEX_VOXEL_SPACE_OBJECT);
1288         enm.insert("World", NODE_TEX_VOXEL_SPACE_WORLD);
1289
1290         return enm;
1291 }
1292
1293 ShaderEnum PointDensityTextureNode::space_enum = point_density_space_init();
1294
1295 PointDensityTextureNode::PointDensityTextureNode()
1296 : ShaderNode("point_density")
1297 {
1298         image_manager = NULL;
1299         slot = -1;
1300         filename = "";
1301         space = ustring("Object");
1302         builtin_data = NULL;
1303         interpolation = INTERPOLATION_LINEAR;
1304
1305         tfm = transform_identity();
1306
1307         add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::POSITION);
1308         add_output("Density", SHADER_SOCKET_FLOAT);
1309         add_output("Color", SHADER_SOCKET_COLOR);
1310 }
1311
1312 PointDensityTextureNode::~PointDensityTextureNode()
1313 {
1314         if(image_manager) {
1315                 image_manager->remove_image(filename,
1316                                             builtin_data,
1317                                             interpolation,
1318                                             EXTENSION_CLIP);
1319         }
1320 }
1321
1322 ShaderNode *PointDensityTextureNode::clone() const
1323 {
1324         PointDensityTextureNode *node = new PointDensityTextureNode(*this);
1325         node->image_manager = NULL;
1326         node->slot = -1;
1327         return node;
1328 }
1329
1330 void PointDensityTextureNode::attributes(Shader *shader,
1331                                          AttributeRequestSet *attributes)
1332 {
1333         if(shader->has_volume)
1334                 attributes->add(ATTR_STD_GENERATED_TRANSFORM);
1335
1336         ShaderNode::attributes(shader, attributes);
1337 }
1338
1339 void PointDensityTextureNode::compile(SVMCompiler& compiler)
1340 {
1341         ShaderInput *vector_in = input("Vector");
1342         ShaderOutput *density_out = output("Density");
1343         ShaderOutput *color_out = output("Color");
1344
1345         const bool use_density = !density_out->links.empty();
1346         const bool use_color = !color_out->links.empty();
1347
1348         image_manager = compiler.image_manager;
1349
1350         if(use_density || use_color) {
1351                 if(slot == -1) {
1352                         bool is_float, is_linear;
1353                         slot = image_manager->add_image(filename, builtin_data,
1354                                                         false, 0,
1355                                                         is_float, is_linear,
1356                                                         interpolation,
1357                                                         EXTENSION_CLIP,
1358                                                         true);
1359                 }
1360
1361                 if(slot != -1) {
1362                         compiler.stack_assign(vector_in);
1363                         compiler.add_node(NODE_TEX_VOXEL,
1364                                           slot,
1365                                           compiler.encode_uchar4(compiler.stack_assign(vector_in),
1366                                                                  compiler.stack_assign_if_linked(density_out),
1367                                                                  compiler.stack_assign_if_linked(color_out),
1368                                                                  space_enum[space]));
1369                         if(space == "World") {
1370                                 compiler.add_node(tfm.x);
1371                                 compiler.add_node(tfm.y);
1372                                 compiler.add_node(tfm.z);
1373                                 compiler.add_node(tfm.w);
1374                         }
1375                 }
1376                 else {
1377                         if(use_density) {
1378                                 compiler.add_node(NODE_VALUE_F,
1379                                                                   __float_as_int(0.0f),
1380                                                                   compiler.stack_assign(density_out));
1381                         }
1382                         if (use_color) {
1383                                 compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
1384                                 compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R,
1385                                                                                                                         TEX_IMAGE_MISSING_G,
1386                                                                                                                         TEX_IMAGE_MISSING_B));
1387                         }
1388                 }
1389         }
1390 }
1391
1392 void PointDensityTextureNode::compile(OSLCompiler& compiler)
1393 {
1394         ShaderOutput *density_out = output("Density");
1395         ShaderOutput *color_out = output("Color");
1396
1397         const bool use_density = !density_out->links.empty();
1398         const bool use_color = !color_out->links.empty();
1399
1400         image_manager = compiler.image_manager;
1401
1402         if(use_density || use_color) {
1403                 if(slot == -1) {
1404                         bool is_float, is_linear;
1405                         slot = image_manager->add_image(filename, builtin_data,
1406                                                         false, 0,
1407                                                         is_float, is_linear,
1408                                                         interpolation,
1409                                                         EXTENSION_CLIP,
1410                                                         true);
1411                 }
1412
1413                 if(slot != -1) {
1414                         compiler.parameter("filename", string_printf("@%d", slot).c_str());
1415                 }
1416                 if(space == "World") {
1417                         compiler.parameter("mapping", transform_transpose(tfm));
1418                         compiler.parameter("use_mapping", 1);
1419                 }
1420                 switch(interpolation) {
1421                         case INTERPOLATION_CLOSEST:
1422                                 compiler.parameter("interpolation", "closest");
1423                                 break;
1424                         case INTERPOLATION_CUBIC:
1425                                 compiler.parameter("interpolation", "cubic");
1426                                 break;
1427                         case INTERPOLATION_LINEAR:
1428                         default:
1429                                 compiler.parameter("interpolation", "linear");
1430                                 break;
1431                 }
1432
1433                 compiler.add(this, "node_voxel_texture");
1434         }
1435 }
1436
1437 /* Normal */
1438
1439 NormalNode::NormalNode()
1440 : ShaderNode("normal")
1441 {
1442         direction = make_float3(0.0f, 0.0f, 1.0f);
1443
1444         add_input("Normal", SHADER_SOCKET_NORMAL);
1445         add_output("Normal", SHADER_SOCKET_NORMAL);
1446         add_output("Dot",  SHADER_SOCKET_FLOAT);
1447 }
1448
1449 void NormalNode::compile(SVMCompiler& compiler)
1450 {
1451         ShaderInput *normal_in = input("Normal");
1452         ShaderOutput *normal_out = output("Normal");
1453         ShaderOutput *dot_out = output("Dot");
1454
1455         compiler.add_node(NODE_NORMAL,
1456                 compiler.stack_assign(normal_in),
1457                 compiler.stack_assign(normal_out),
1458                 compiler.stack_assign(dot_out));
1459         compiler.add_node(
1460                 __float_as_int(direction.x),
1461                 __float_as_int(direction.y),
1462                 __float_as_int(direction.z));
1463 }
1464
1465 void NormalNode::compile(OSLCompiler& compiler)
1466 {
1467         compiler.parameter_normal("Direction", direction);
1468         compiler.add(this, "node_normal");
1469 }
1470
1471 /* Mapping */
1472
1473 MappingNode::MappingNode()
1474 : ShaderNode("mapping")
1475 {
1476         add_input("Vector", SHADER_SOCKET_POINT);
1477         add_output("Vector", SHADER_SOCKET_POINT);
1478 }
1479
1480 void MappingNode::compile(SVMCompiler& compiler)
1481 {
1482         ShaderInput *vector_in = input("Vector");
1483         ShaderOutput *vector_out = output("Vector");
1484
1485         tex_mapping.compile(compiler, compiler.stack_assign(vector_in), compiler.stack_assign(vector_out));
1486 }
1487
1488 void MappingNode::compile(OSLCompiler& compiler)
1489 {
1490         Transform tfm = transform_transpose(tex_mapping.compute_transform());
1491         compiler.parameter("Matrix", tfm);
1492         compiler.parameter_point("mapping_min", tex_mapping.min);
1493         compiler.parameter_point("mapping_max", tex_mapping.max);
1494         compiler.parameter("use_minmax", tex_mapping.use_minmax);
1495
1496         compiler.add(this, "node_mapping");
1497 }
1498
1499 /* Convert */
1500
1501 ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_, bool autoconvert)
1502 : ShaderNode("convert")
1503 {
1504         from = from_;
1505         to = to_;
1506
1507         if(autoconvert) {
1508                 if(from == to)
1509                         special_type = SHADER_SPECIAL_TYPE_PROXY;
1510                 else
1511                         special_type = SHADER_SPECIAL_TYPE_AUTOCONVERT;
1512         }
1513
1514         if(from == SHADER_SOCKET_FLOAT)
1515                 add_input("Val", SHADER_SOCKET_FLOAT);
1516         else if(from == SHADER_SOCKET_INT)
1517                 add_input("ValInt", SHADER_SOCKET_INT);
1518         else if(from == SHADER_SOCKET_COLOR)
1519                 add_input("Color", SHADER_SOCKET_COLOR);
1520         else if(from == SHADER_SOCKET_VECTOR)
1521                 add_input("Vector", SHADER_SOCKET_VECTOR);
1522         else if(from == SHADER_SOCKET_POINT)
1523                 add_input("Point", SHADER_SOCKET_POINT);
1524         else if(from == SHADER_SOCKET_NORMAL)
1525                 add_input("Normal", SHADER_SOCKET_NORMAL);
1526         else if(from == SHADER_SOCKET_STRING)
1527                 add_input("String", SHADER_SOCKET_STRING);
1528         else if(from == SHADER_SOCKET_CLOSURE)
1529                 add_input("Closure", SHADER_SOCKET_CLOSURE);
1530         else
1531                 assert(0);
1532
1533         if(to == SHADER_SOCKET_FLOAT)
1534                 add_output("Val", SHADER_SOCKET_FLOAT);
1535         else if(to == SHADER_SOCKET_INT)
1536                 add_output("ValInt", SHADER_SOCKET_INT);
1537         else if(to == SHADER_SOCKET_COLOR)
1538                 add_output("Color", SHADER_SOCKET_COLOR);
1539         else if(to == SHADER_SOCKET_VECTOR)
1540                 add_output("Vector", SHADER_SOCKET_VECTOR);
1541         else if(to == SHADER_SOCKET_POINT)
1542                 add_output("Point", SHADER_SOCKET_POINT);
1543         else if(to == SHADER_SOCKET_NORMAL)
1544                 add_output("Normal", SHADER_SOCKET_NORMAL);
1545         else if(to == SHADER_SOCKET_STRING)
1546                 add_output("String", SHADER_SOCKET_STRING);
1547         else if(to == SHADER_SOCKET_CLOSURE)
1548                 add_output("Closure", SHADER_SOCKET_CLOSURE);
1549         else
1550                 assert(0);
1551 }
1552
1553 bool ConvertNode::constant_fold(ShaderGraph * /*graph*/,
1554                                 ShaderOutput * /*socket*/,
1555                                 float3 *optimized_value)
1556 {
1557         ShaderInput *in = inputs[0];
1558         float3 value = in->value;
1559
1560         /* TODO(DingTo): conversion from/to int is not supported yet, don't fold in that case */
1561
1562         if(in->link == NULL) {
1563                 if(from == SHADER_SOCKET_FLOAT) {
1564                         if(to == SHADER_SOCKET_INT)
1565                                 /* float to int */
1566                                 return false;
1567                         else
1568                                 /* float to float3 */
1569                                 *optimized_value = make_float3(value.x, value.x, value.x);
1570                 }
1571                 else if(from == SHADER_SOCKET_INT) {
1572                         if(to == SHADER_SOCKET_FLOAT)
1573                                 /* int to float */
1574                                 return false;
1575                         else
1576                                 /* int to vector/point/normal */
1577                                 return false;
1578                 }
1579                 else if(to == SHADER_SOCKET_FLOAT) {
1580                         if(from == SHADER_SOCKET_COLOR)
1581                                 /* color to float */
1582                                 optimized_value->x = linear_rgb_to_gray(value);
1583                         else
1584                                 /* vector/point/normal to float */
1585                                 optimized_value->x = average(value);
1586                 }
1587                 else if(to == SHADER_SOCKET_INT) {
1588                         if(from == SHADER_SOCKET_COLOR)
1589                                 /* color to int */
1590                                 return false;
1591                         else
1592                                 /* vector/point/normal to int */
1593                                 return false;
1594                 }
1595                 else {
1596                         *optimized_value = value;
1597                 }
1598
1599                 return true;
1600         }
1601
1602         return false;
1603 }
1604
1605 void ConvertNode::compile(SVMCompiler& compiler)
1606 {
1607         /* constant folding should eliminate proxy nodes */
1608         assert(from != to);
1609
1610         ShaderInput *in = inputs[0];
1611         ShaderOutput *out = outputs[0];
1612
1613         if(from == SHADER_SOCKET_FLOAT) {
1614                 if(to == SHADER_SOCKET_INT)
1615                         /* float to int */
1616                         compiler.add_node(NODE_CONVERT, NODE_CONVERT_FI, compiler.stack_assign(in), compiler.stack_assign(out));
1617                 else
1618                         /* float to float3 */
1619                         compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, compiler.stack_assign(in), compiler.stack_assign(out));
1620         }
1621         else if(from == SHADER_SOCKET_INT) {
1622                 if(to == SHADER_SOCKET_FLOAT)
1623                         /* int to float */
1624                         compiler.add_node(NODE_CONVERT, NODE_CONVERT_IF, compiler.stack_assign(in), compiler.stack_assign(out));
1625                 else
1626                         /* int to vector/point/normal */
1627                         compiler.add_node(NODE_CONVERT, NODE_CONVERT_IV, compiler.stack_assign(in), compiler.stack_assign(out));
1628         }
1629         else if(to == SHADER_SOCKET_FLOAT) {
1630                 if(from == SHADER_SOCKET_COLOR)
1631                         /* color to float */
1632                         compiler.add_node(NODE_CONVERT, NODE_CONVERT_CF, compiler.stack_assign(in), compiler.stack_assign(out));
1633                 else
1634                         /* vector/point/normal to float */
1635                         compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, compiler.stack_assign(in), compiler.stack_assign(out));
1636         }
1637         else if(to == SHADER_SOCKET_INT) {
1638                 if(from == SHADER_SOCKET_COLOR)
1639                         /* color to int */
1640                         compiler.add_node(NODE_CONVERT, NODE_CONVERT_CI, compiler.stack_assign(in), compiler.stack_assign(out));
1641                 else
1642                         /* vector/point/normal to int */
1643                         compiler.add_node(NODE_CONVERT, NODE_CONVERT_VI, compiler.stack_assign(in), compiler.stack_assign(out));
1644         }
1645         else {
1646                 /* float3 to float3 */
1647                 if(in->link) {
1648                         /* no op in SVM */
1649                         compiler.stack_link(in, out);
1650                 }
1651                 else {
1652                         /* set 0,0,0 value */
1653                         compiler.add_node(NODE_VALUE_V, compiler.stack_assign(out));
1654                         compiler.add_node(NODE_VALUE_V, in->value);
1655                 }
1656         }
1657 }
1658
1659 void ConvertNode::compile(OSLCompiler& compiler)
1660 {
1661         /* constant folding should eliminate proxy nodes */
1662         assert(from != to);
1663
1664         if(from == SHADER_SOCKET_FLOAT)
1665                 compiler.add(this, "node_convert_from_float");
1666         else if(from == SHADER_SOCKET_INT)
1667                 compiler.add(this, "node_convert_from_int");
1668         else if(from == SHADER_SOCKET_COLOR)
1669                 compiler.add(this, "node_convert_from_color");
1670         else if(from == SHADER_SOCKET_VECTOR)
1671                 compiler.add(this, "node_convert_from_vector");
1672         else if(from == SHADER_SOCKET_POINT)
1673                 compiler.add(this, "node_convert_from_point");
1674         else if(from == SHADER_SOCKET_NORMAL)
1675                 compiler.add(this, "node_convert_from_normal");
1676         else
1677                 assert(0);
1678 }
1679
1680 /* BSDF Closure */
1681
1682 BsdfNode::BsdfNode(bool scattering_)
1683 : ShaderNode("bsdf"), scattering(scattering_)
1684 {
1685         special_type = SHADER_SPECIAL_TYPE_CLOSURE;
1686
1687         add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
1688         add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL);
1689         add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
1690
1691         if(scattering) {
1692                 closure = CLOSURE_BSSRDF_CUBIC_ID;
1693                 add_output("BSSRDF", SHADER_SOCKET_CLOSURE);
1694         }
1695         else {
1696                 closure = CLOSURE_BSDF_DIFFUSE_ID;
1697                 add_output("BSDF", SHADER_SOCKET_CLOSURE);
1698         }
1699 }
1700
1701 void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3, ShaderInput *param4)
1702 {
1703         ShaderInput *color_in = input("Color");
1704         ShaderInput *normal_in = input("Normal");
1705         ShaderInput *tangent_in = input("Tangent");
1706
1707         if(color_in->link)
1708                 compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
1709         else
1710                 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value);
1711
1712         int normal_offset = compiler.stack_assign_if_linked(normal_in);
1713         int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) : SVM_STACK_INVALID;
1714         int param3_offset = (param3) ? compiler.stack_assign(param3) : SVM_STACK_INVALID;
1715         int param4_offset = (param4) ? compiler.stack_assign(param4) : SVM_STACK_INVALID;
1716
1717         compiler.add_node(NODE_CLOSURE_BSDF,
1718                 compiler.encode_uchar4(closure,
1719                         (param1)? compiler.stack_assign(param1): SVM_STACK_INVALID,
1720                         (param2)? compiler.stack_assign(param2): SVM_STACK_INVALID,
1721                         compiler.closure_mix_weight_offset()),
1722                 __float_as_int((param1)? param1->value.x: 0.0f),
1723                 __float_as_int((param2)? param2->value.x: 0.0f));
1724
1725         compiler.add_node(normal_offset, tangent_offset, param3_offset, param4_offset);
1726 }
1727
1728 void BsdfNode::compile(SVMCompiler& compiler)
1729 {
1730         compile(compiler, NULL, NULL);
1731 }
1732
1733 void BsdfNode::compile(OSLCompiler& /*compiler*/)
1734 {
1735         assert(0);
1736 }
1737
1738 /* Anisotropic BSDF Closure */
1739
1740 static ShaderEnum aniso_distribution_init()
1741 {
1742         ShaderEnum enm;
1743
1744         enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID);
1745         enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID);
1746         enm.insert("Ashikhmin-Shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID);
1747
1748         return enm;
1749 }
1750
1751 ShaderEnum AnisotropicBsdfNode::distribution_enum = aniso_distribution_init();
1752
1753 AnisotropicBsdfNode::AnisotropicBsdfNode()
1754 {
1755         closure = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
1756         distribution = ustring("GGX");
1757
1758         add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT);
1759
1760         add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f);
1761         add_input("Anisotropy", SHADER_SOCKET_FLOAT, 0.5f);
1762         add_input("Rotation", SHADER_SOCKET_FLOAT, 0.0f);
1763 }
1764
1765 void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
1766 {
1767         if(shader->has_surface) {
1768                 ShaderInput *tangent_in = input("Tangent");
1769
1770                 if(!tangent_in->link)
1771                         attributes->add(ATTR_STD_GENERATED);
1772         }
1773
1774         ShaderNode::attributes(shader, attributes);
1775 }
1776
1777 void AnisotropicBsdfNode::compile(SVMCompiler& compiler)
1778 {
1779         closure = (ClosureType)distribution_enum[distribution];
1780
1781         BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"));
1782 }
1783
1784 void AnisotropicBsdfNode::compile(OSLCompiler& compiler)
1785 {
1786         compiler.parameter("distribution", distribution);
1787         compiler.add(this, "node_anisotropic_bsdf");
1788 }
1789
1790 /* Glossy BSDF Closure */
1791
1792 static ShaderEnum glossy_distribution_init()
1793 {
1794         ShaderEnum enm;
1795
1796         enm.insert("Sharp", CLOSURE_BSDF_REFLECTION_ID);
1797         enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
1798         enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID);
1799         enm.insert("Ashikhmin-Shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
1800
1801         return enm;
1802 }
1803
1804 ShaderEnum GlossyBsdfNode::distribution_enum = glossy_distribution_init();
1805
1806 GlossyBsdfNode::GlossyBsdfNode()
1807 {
1808         closure = CLOSURE_BSDF_MICROFACET_GGX_ID;
1809         distribution = ustring("GGX");
1810         distribution_orig = ustring("");
1811
1812         add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f);
1813 }
1814
1815 void GlossyBsdfNode::simplify_settings(Scene *scene)
1816 {
1817         if(distribution_orig == "") {
1818                 distribution_orig = distribution;
1819         }
1820         Integrator *integrator = scene->integrator;
1821         if(integrator->filter_glossy == 0.0f) {
1822                 /* Fallback to Sharp closure for Roughness close to 0.
1823                  * Note: Keep the epsilon in sync with kernel!
1824                  */
1825                 ShaderInput *roughness_input = input("Roughness");
1826                 if(!roughness_input->link && roughness_input->value.x <= 1e-4f) {
1827                         distribution = ustring("Sharp");
1828                 }
1829         }
1830         else {
1831                 /* Rollback to original distribution when filter glossy is used. */
1832                 distribution = distribution_orig;
1833         }
1834         closure = (ClosureType)distribution_enum[distribution];
1835 }
1836
1837 bool GlossyBsdfNode::has_integrator_dependency()
1838 {
1839         ShaderInput *roughness_input = input("Roughness");
1840         return !roughness_input->link && roughness_input->value.x <= 1e-4f;
1841 }
1842
1843 void GlossyBsdfNode::compile(SVMCompiler& compiler)
1844 {
1845         closure = (ClosureType)distribution_enum[distribution];
1846
1847         if(closure == CLOSURE_BSDF_REFLECTION_ID)
1848                 BsdfNode::compile(compiler, NULL, NULL);
1849         else
1850                 BsdfNode::compile(compiler, input("Roughness"), NULL);
1851 }
1852
1853 void GlossyBsdfNode::compile(OSLCompiler& compiler)
1854 {
1855         compiler.parameter("distribution", distribution);
1856         compiler.add(this, "node_glossy_bsdf");
1857 }
1858
1859 /* Glass BSDF Closure */
1860
1861 static ShaderEnum glass_distribution_init()
1862 {
1863         ShaderEnum enm;
1864
1865         enm.insert("Sharp", CLOSURE_BSDF_SHARP_GLASS_ID);
1866         enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID);
1867         enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
1868
1869         return enm;
1870 }
1871
1872 ShaderEnum GlassBsdfNode::distribution_enum = glass_distribution_init();
1873
1874 GlassBsdfNode::GlassBsdfNode()
1875 {
1876         closure = CLOSURE_BSDF_SHARP_GLASS_ID;
1877         distribution = ustring("Sharp");
1878         distribution_orig = ustring("");
1879
1880         add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f);
1881         add_input("IOR", SHADER_SOCKET_FLOAT, 0.3f);
1882 }
1883
1884 void GlassBsdfNode::simplify_settings(Scene *scene)
1885 {
1886         if(distribution_orig == "") {
1887                 distribution_orig = distribution;
1888         }
1889         Integrator *integrator = scene->integrator;
1890         if(integrator->filter_glossy == 0.0f) {
1891                 /* Fallback to Sharp closure for Roughness close to 0.
1892                  * Note: Keep the epsilon in sync with kernel!
1893                  */
1894                 ShaderInput *roughness_input = input("Roughness");
1895                 if(!roughness_input->link && roughness_input->value.x <= 1e-4f) {
1896                         distribution = ustring("Sharp");
1897                 }
1898         }
1899         else {
1900                 /* Rollback to original distribution when filter glossy is used. */
1901                 distribution = distribution_orig;
1902         }
1903         closure = (ClosureType)distribution_enum[distribution];
1904 }
1905
1906 bool GlassBsdfNode::has_integrator_dependency()
1907 {
1908         ShaderInput *roughness_input = input("Roughness");
1909         return !roughness_input->link && roughness_input->value.x <= 1e-4f;
1910 }
1911
1912 void GlassBsdfNode::compile(SVMCompiler& compiler)
1913 {
1914         closure = (ClosureType)distribution_enum[distribution];
1915
1916         if(closure == CLOSURE_BSDF_SHARP_GLASS_ID)
1917                 BsdfNode::compile(compiler, NULL, input("IOR"));
1918         else
1919                 BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
1920 }
1921
1922 void GlassBsdfNode::compile(OSLCompiler& compiler)
1923 {
1924         compiler.parameter("distribution", distribution);
1925         compiler.add(this, "node_glass_bsdf");
1926 }
1927
1928 /* Refraction BSDF Closure */
1929
1930 static ShaderEnum refraction_distribution_init()
1931 {
1932         ShaderEnum enm;
1933
1934         enm.insert("Sharp", CLOSURE_BSDF_REFRACTION_ID);
1935         enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
1936         enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
1937
1938         return enm;
1939 }
1940
1941 ShaderEnum RefractionBsdfNode::distribution_enum = refraction_distribution_init();
1942
1943 RefractionBsdfNode::RefractionBsdfNode()
1944 {
1945         closure = CLOSURE_BSDF_REFRACTION_ID;
1946         distribution = ustring("Sharp");
1947         distribution_orig = ustring("");
1948
1949         add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f);
1950         add_input("IOR", SHADER_SOCKET_FLOAT, 0.3f);
1951 }
1952
1953 void RefractionBsdfNode::simplify_settings(Scene *scene)
1954 {
1955         if(distribution_orig == "") {
1956                 distribution_orig = distribution;
1957         }
1958         Integrator *integrator = scene->integrator;
1959         if(integrator->filter_glossy == 0.0f) {
1960                 /* Fallback to Sharp closure for Roughness close to 0.
1961                  * Note: Keep the epsilon in sync with kernel!
1962                  */
1963                 ShaderInput *roughness_input = input("Roughness");
1964                 if(!roughness_input->link && roughness_input->value.x <= 1e-4f) {
1965                         distribution = ustring("Sharp");
1966                 }
1967         }
1968         else {
1969                 /* Rollback to original distribution when filter glossy is used. */
1970                 distribution = distribution_orig;
1971         }
1972         closure = (ClosureType)distribution_enum[distribution];
1973 }
1974
1975 bool RefractionBsdfNode::has_integrator_dependency()
1976 {
1977         ShaderInput *roughness_input = input("Roughness");
1978         return !roughness_input->link && roughness_input->value.x <= 1e-4f;
1979 }
1980
1981 void RefractionBsdfNode::compile(SVMCompiler& compiler)
1982 {
1983         closure = (ClosureType)distribution_enum[distribution];
1984
1985         if(closure == CLOSURE_BSDF_REFRACTION_ID)
1986                 BsdfNode::compile(compiler, NULL, input("IOR"));
1987         else
1988                 BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
1989 }
1990
1991 void RefractionBsdfNode::compile(OSLCompiler& compiler)
1992 {
1993         compiler.parameter("distribution", distribution);
1994         compiler.add(this, "node_refraction_bsdf");
1995 }
1996
1997 /* Toon BSDF Closure */
1998
1999 static ShaderEnum toon_component_init()
2000 {
2001         ShaderEnum enm;
2002
2003         enm.insert("Diffuse", CLOSURE_BSDF_DIFFUSE_TOON_ID);
2004         enm.insert("Glossy", CLOSURE_BSDF_GLOSSY_TOON_ID);
2005
2006         return enm;
2007 }
2008
2009 ShaderEnum ToonBsdfNode::component_enum = toon_component_init();
2010
2011 ToonBsdfNode::ToonBsdfNode()
2012 {
2013         closure = CLOSURE_BSDF_DIFFUSE_TOON_ID;
2014         component = ustring("Diffuse");
2015
2016         add_input("Size", SHADER_SOCKET_FLOAT, 0.5f);
2017         add_input("Smooth", SHADER_SOCKET_FLOAT, 0.0f);
2018 }
2019
2020 void ToonBsdfNode::compile(SVMCompiler& compiler)
2021 {
2022         closure = (ClosureType)component_enum[component];
2023         
2024         BsdfNode::compile(compiler, input("Size"), input("Smooth"));
2025 }
2026
2027 void ToonBsdfNode::compile(OSLCompiler& compiler)
2028 {
2029         compiler.parameter("component", component);
2030         compiler.add(this, "node_toon_bsdf");
2031 }
2032
2033 /* Velvet BSDF Closure */
2034
2035 VelvetBsdfNode::VelvetBsdfNode()
2036 {
2037         closure = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID;
2038
2039         add_input("Sigma", SHADER_SOCKET_FLOAT, 1.0f);
2040 }
2041
2042 void VelvetBsdfNode::compile(SVMCompiler& compiler)
2043 {
2044         BsdfNode::compile(compiler, input("Sigma"), NULL);
2045 }
2046
2047 void VelvetBsdfNode::compile(OSLCompiler& compiler)
2048 {
2049         compiler.add(this, "node_velvet_bsdf");
2050 }
2051
2052 /* Diffuse BSDF Closure */
2053
2054 DiffuseBsdfNode::DiffuseBsdfNode()
2055 {
2056         closure = CLOSURE_BSDF_DIFFUSE_ID;
2057         add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f);
2058 }
2059
2060 void DiffuseBsdfNode::compile(SVMCompiler& compiler)
2061 {
2062         BsdfNode::compile(compiler, input("Roughness"), NULL);
2063 }
2064
2065 void DiffuseBsdfNode::compile(OSLCompiler& compiler)
2066 {
2067         compiler.add(this, "node_diffuse_bsdf");
2068 }
2069
2070 /* Translucent BSDF Closure */
2071
2072 TranslucentBsdfNode::TranslucentBsdfNode()
2073 {
2074         closure = CLOSURE_BSDF_TRANSLUCENT_ID;
2075 }
2076
2077 void TranslucentBsdfNode::compile(SVMCompiler& compiler)
2078 {
2079         BsdfNode::compile(compiler, NULL, NULL);
2080 }
2081
2082 void TranslucentBsdfNode::compile(OSLCompiler& compiler)
2083 {
2084         compiler.add(this, "node_translucent_bsdf");
2085 }
2086
2087 /* Transparent BSDF Closure */
2088
2089 TransparentBsdfNode::TransparentBsdfNode()
2090 {
2091         name = "transparent";
2092         closure = CLOSURE_BSDF_TRANSPARENT_ID;
2093 }
2094
2095 void TransparentBsdfNode::compile(SVMCompiler& compiler)
2096 {
2097         BsdfNode::compile(compiler, NULL, NULL);
2098 }
2099
2100 void TransparentBsdfNode::compile(OSLCompiler& compiler)
2101 {
2102         compiler.add(this, "node_transparent_bsdf");
2103 }
2104
2105 /* Subsurface Scattering Closure */
2106
2107 static ShaderEnum subsurface_falloff_init()
2108 {
2109         ShaderEnum enm;
2110
2111         enm.insert("Cubic", CLOSURE_BSSRDF_CUBIC_ID);
2112         enm.insert("Gaussian", CLOSURE_BSSRDF_GAUSSIAN_ID);
2113         enm.insert("Burley", CLOSURE_BSSRDF_BURLEY_ID);
2114
2115         return enm;
2116 }
2117
2118 ShaderEnum SubsurfaceScatteringNode::falloff_enum = subsurface_falloff_init();
2119
2120 SubsurfaceScatteringNode::SubsurfaceScatteringNode()
2121 : BsdfNode(true)
2122 {
2123         name = "subsurface_scattering";
2124         closure = CLOSURE_BSSRDF_CUBIC_ID;
2125
2126         add_input("Scale", SHADER_SOCKET_FLOAT, 0.01f);
2127         add_input("Radius", SHADER_SOCKET_VECTOR, make_float3(0.1f, 0.1f, 0.1f));
2128         add_input("Sharpness", SHADER_SOCKET_FLOAT, 0.0f);
2129         add_input("Texture Blur", SHADER_SOCKET_FLOAT, 1.0f);
2130 }
2131
2132 void SubsurfaceScatteringNode::compile(SVMCompiler& compiler)
2133 {
2134         BsdfNode::compile(compiler, input("Scale"), input("Texture Blur"), input("Radius"), input("Sharpness"));
2135 }
2136
2137 void SubsurfaceScatteringNode::compile(OSLCompiler& compiler)
2138 {
2139         compiler.parameter("Falloff", falloff_enum[closure]);
2140         compiler.add(this, "node_subsurface_scattering");
2141 }
2142
2143 bool SubsurfaceScatteringNode::has_bssrdf_bump()
2144 {
2145         /* detect if anything is plugged into the normal input besides the default */
2146         ShaderInput *normal_in = input("Normal");
2147         return (normal_in->link && normal_in->link->parent->special_type != SHADER_SPECIAL_TYPE_GEOMETRY);
2148 }
2149
2150 /* Emissive Closure */
2151
2152 EmissionNode::EmissionNode()
2153 : ShaderNode("emission")
2154 {
2155         add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
2156         add_input("Strength", SHADER_SOCKET_FLOAT, 10.0f);
2157         add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
2158
2159         add_output("Emission", SHADER_SOCKET_CLOSURE);
2160 }
2161
2162 void EmissionNode::compile(SVMCompiler& compiler)
2163 {
2164         ShaderInput *color_in = input("Color");
2165         ShaderInput *strength_in = input("Strength");
2166
2167         if(color_in->link || strength_in->link) {
2168                 compiler.add_node(NODE_EMISSION_WEIGHT,
2169                                   compiler.stack_assign(color_in),
2170                                                   compiler.stack_assign(strength_in));
2171         }
2172         else
2173                 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value * strength_in->value.x);
2174
2175         compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset());
2176 }
2177
2178 void EmissionNode::compile(OSLCompiler& compiler)
2179 {
2180         compiler.add(this, "node_emission");
2181 }
2182
2183 bool EmissionNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, float3 * /*optimized_value*/)
2184 {
2185         ShaderInput *color_in = input("Color");
2186         ShaderInput *strength_in = input("Strength");
2187
2188         return ((!color_in->link && color_in->value == make_float3(0.0f, 0.0f, 0.0f)) ||
2189                 (!strength_in->link && strength_in->value.x == 0.0f));
2190 }
2191
2192 /* Background Closure */
2193
2194 BackgroundNode::BackgroundNode()
2195 : ShaderNode("background")
2196 {
2197         add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
2198         add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f);
2199         add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
2200
2201         add_output("Background", SHADER_SOCKET_CLOSURE);
2202 }
2203
2204 void BackgroundNode::compile(SVMCompiler& compiler)
2205 {
2206         ShaderInput *color_in = input("Color");
2207         ShaderInput *strength_in = input("Strength");
2208
2209         if(color_in->link || strength_in->link) {
2210                 compiler.add_node(NODE_EMISSION_WEIGHT,
2211                                   compiler.stack_assign(color_in),
2212                                                   compiler.stack_assign(strength_in));
2213         }
2214         else
2215                 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value*strength_in->value.x);
2216
2217         compiler.add_node(NODE_CLOSURE_BACKGROUND, compiler.closure_mix_weight_offset());
2218 }
2219
2220 void BackgroundNode::compile(OSLCompiler& compiler)
2221 {
2222         compiler.add(this, "node_background");
2223 }
2224
2225 bool BackgroundNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, float3 * /*optimized_value*/)
2226 {
2227         ShaderInput *color_in = input("Color");
2228         ShaderInput *strength_in = input("Strength");
2229
2230         return ((!color_in->link && color_in->value == make_float3(0.0f, 0.0f, 0.0f)) ||
2231                 (!strength_in->link && strength_in->value.x == 0.0f));
2232 }
2233
2234 /* Holdout Closure */
2235
2236 HoldoutNode::HoldoutNode()
2237 : ShaderNode("holdout")
2238 {
2239         add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
2240         add_input("VolumeMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
2241
2242         add_output("Holdout", SHADER_SOCKET_CLOSURE);
2243 }
2244
2245 void HoldoutNode::compile(SVMCompiler& compiler)
2246 {
2247         float3 value = make_float3(1.0f, 1.0f, 1.0f);
2248
2249         compiler.add_node(NODE_CLOSURE_SET_WEIGHT, value);
2250         compiler.add_node(NODE_CLOSURE_HOLDOUT, compiler.closure_mix_weight_offset());
2251 }
2252
2253 void HoldoutNode::compile(OSLCompiler& compiler)
2254 {
2255         compiler.add(this, "node_holdout");
2256 }
2257
2258 /* Ambient Occlusion */
2259
2260 AmbientOcclusionNode::AmbientOcclusionNode()
2261 : ShaderNode("ambient_occlusion")
2262 {
2263         add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
2264         add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
2265         add_input("SurfaceMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
2266
2267         add_output("AO", SHADER_SOCKET_CLOSURE);
2268 }
2269
2270 void AmbientOcclusionNode::compile(SVMCompiler& compiler)
2271 {
2272         ShaderInput *color_in = input("Color");
2273
2274         if(color_in->link)
2275                 compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
2276         else
2277                 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value);
2278
2279         compiler.add_node(NODE_CLOSURE_AMBIENT_OCCLUSION, compiler.closure_mix_weight_offset());
2280 }
2281
2282 void AmbientOcclusionNode::compile(OSLCompiler& compiler)
2283 {
2284         compiler.add(this, "node_ambient_occlusion");
2285 }
2286
2287 /* Volume Closure */
2288
2289 VolumeNode::VolumeNode()
2290 : ShaderNode("volume")
2291 {
2292         closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
2293
2294         add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
2295         add_input("Density", SHADER_SOCKET_FLOAT, 1.0f);
2296         add_input("VolumeMixWeight", SHADER_SOCKET_FLOAT, 0.0f, ShaderInput::USE_SVM);
2297
2298         add_output("Volume", SHADER_SOCKET_CLOSURE);
2299 }
2300
2301 void VolumeNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2)
2302 {
2303         ShaderInput *color_in = input("Color");
2304
2305         if(color_in->link)
2306                 compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
2307         else
2308                 compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value);
2309         
2310         compiler.add_node(NODE_CLOSURE_VOLUME,
2311                 compiler.encode_uchar4(closure,
2312                         (param1)? compiler.stack_assign(param1): SVM_STACK_INVALID,
2313                         (param2)? compiler.stack_assign(param2): SVM_STACK_INVALID,
2314                         compiler.closure_mix_weight_offset()),
2315                 __float_as_int((param1)? param1->value.x: 0.0f),
2316                 __float_as_int((param2)? param2->value.x: 0.0f));
2317 }
2318
2319 void VolumeNode::compile(SVMCompiler& compiler)
2320 {
2321         compile(compiler, NULL, NULL);
2322 }
2323
2324 void VolumeNode::compile(OSLCompiler& /*compiler*/)
2325 {
2326         assert(0);
2327 }
2328
2329 /* Absorption Volume Closure */
2330
2331 AbsorptionVolumeNode::AbsorptionVolumeNode()
2332 {
2333         closure = CLOSURE_VOLUME_ABSORPTION_ID;
2334 }
2335
2336 void AbsorptionVolumeNode::compile(SVMCompiler& compiler)
2337 {
2338         VolumeNode::compile(compiler, input("Density"), NULL);
2339 }
2340
2341 void AbsorptionVolumeNode::compile(OSLCompiler& compiler)
2342 {
2343         compiler.add(this, "node_absorption_volume");
2344 }
2345
2346 /* Scatter Volume Closure */
2347
2348 ScatterVolumeNode::ScatterVolumeNode()
2349 {
2350         closure = CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID;
2351         
2352         add_input("Anisotropy", SHADER_SOCKET_FLOAT, 0.0f);
2353 }
2354
2355 void ScatterVolumeNode::compile(SVMCompiler& compiler)
2356 {
2357         VolumeNode::compile(compiler, input("Density"), input("Anisotropy"));
2358 }
2359
2360 void ScatterVolumeNode::compile(OSLCompiler& compiler)
2361 {
2362         compiler.add(this, "node_scatter_volume");
2363 }
2364
2365 /* Hair BSDF Closure */
2366
2367 static ShaderEnum hair_component_init()
2368 {
2369         ShaderEnum enm;
2370
2371         enm.insert("Reflection", CLOSURE_BSDF_HAIR_REFLECTION_ID);
2372         enm.insert("Transmission", CLOSURE_BSDF_HAIR_TRANSMISSION_ID);
2373
2374         return enm;
2375 }
2376
2377 ShaderEnum HairBsdfNode::component_enum = hair_component_init();
2378
2379 HairBsdfNode::HairBsdfNode()
2380 {
2381         closure = CLOSURE_BSDF_HAIR_REFLECTION_ID;
2382         component = ustring("Reflection");
2383
2384         add_input("Offset", SHADER_SOCKET_FLOAT);
2385         add_input("RoughnessU", SHADER_SOCKET_FLOAT);
2386         add_input("RoughnessV", SHADER_SOCKET_FLOAT);
2387         add_input("Tangent", SHADER_SOCKET_VECTOR);
2388 }
2389
2390 void HairBsdfNode::compile(SVMCompiler& compiler)
2391 {
2392         closure = (ClosureType)component_enum[component];
2393
2394         BsdfNode::compile(compiler, input("RoughnessU"), input("RoughnessV"), input("Offset"));
2395 }
2396
2397 void HairBsdfNode::compile(OSLCompiler& compiler)
2398 {
2399         compiler.parameter("component", component);
2400
2401         compiler.add(this, "node_hair_bsdf");
2402 }
2403
2404 /* Geometry */
2405
2406 GeometryNode::GeometryNode()
2407 : ShaderNode("geometry")
2408 {
2409         special_type = SHADER_SPECIAL_TYPE_GEOMETRY;
2410
2411         add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
2412         add_output("Position", SHADER_SOCKET_POINT);
2413         add_output("Normal", SHADER_SOCKET_NORMAL);
2414         add_output("Tangent", SHADER_SOCKET_NORMAL);
2415         add_output("True Normal", SHADER_SOCKET_NORMAL);
2416         add_output("Incoming", SHADER_SOCKET_VECTOR);
2417         add_output("Parametric", SHADER_SOCKET_POINT);
2418         add_output("Backfacing", SHADER_SOCKET_FLOAT);
2419         add_output("Pointiness", SHADER_SOCKET_FLOAT);
2420 }
2421
2422 void GeometryNode::attributes(Shader *shader, AttributeRequestSet *attributes)
2423 {
2424         if(shader->has_surface) {
2425                 if(!output("Tangent")->links.empty()) {
2426                         attributes->add(ATTR_STD_GENERATED);
2427                 }
2428                 if(!output("Pointiness")->links.empty()) {
2429                         attributes->add(ATTR_STD_POINTINESS);
2430                 }
2431         }
2432
2433         ShaderNode::attributes(shader, attributes);
2434 }
2435
2436 void GeometryNode::compile(SVMCompiler& compiler)
2437 {
2438         ShaderOutput *out;
2439         NodeType geom_node = NODE_GEOMETRY;
2440         NodeType attr_node = NODE_ATTR;
2441
2442         if(bump == SHADER_BUMP_DX) {
2443                 geom_node = NODE_GEOMETRY_BUMP_DX;
2444                 attr_node = NODE_ATTR_BUMP_DX;
2445         }
2446         else if(bump == SHADER_BUMP_DY) {
2447                 geom_node = NODE_GEOMETRY_BUMP_DY;
2448                 attr_node = NODE_ATTR_BUMP_DY;
2449         }
2450         
2451         out = output("Position");
2452         if(!out->links.empty()) {
2453                 compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out));
2454         }
2455
2456         out = output("Normal");
2457         if(!out->links.empty()) {
2458                 compiler.add_node(geom_node, NODE_GEOM_N, compiler.stack_assign(out));
2459         }
2460
2461         out = output("Tangent");
2462         if(!out->links.empty()) {
2463                 compiler.add_node(geom_node, NODE_GEOM_T, compiler.stack_assign(out));
2464         }
2465
2466         out = output("True Normal");
2467         if(!out->links.empty()) {
2468                 compiler.add_node(geom_node, NODE_GEOM_Ng, compiler.stack_assign(out));
2469         }
2470
2471         out = output("Incoming");
2472         if(!out->links.empty()) {
2473                 compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out));
2474         }
2475
2476         out = output("Parametric");
2477         if(!out->links.empty()) {
2478                 compiler.add_node(geom_node, NODE_GEOM_uv, compiler.stack_assign(out));
2479         }
2480
2481         out = output("Backfacing");
2482         if(!out->links.empty()) {
2483                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, compiler.stack_assign(out));
2484         }
2485
2486         out = output("Pointiness");
2487         if(!out->links.empty()) {
2488                 if(compiler.output_type() != SHADER_TYPE_VOLUME) {
2489                         compiler.add_node(attr_node,
2490                                           ATTR_STD_POINTINESS,
2491                                           compiler.stack_assign(out),
2492                                           NODE_ATTR_FLOAT);
2493                 }
2494                 else {
2495                         compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out));
2496                 }
2497         }
2498 }
2499
2500 void GeometryNode::compile(OSLCompiler& compiler)
2501 {
2502         if(bump == SHADER_BUMP_DX)
2503                 compiler.parameter("bump_offset", "dx");
2504         else if(bump == SHADER_BUMP_DY)
2505                 compiler.parameter("bump_offset", "dy");
2506         else
2507                 compiler.parameter("bump_offset", "center");
2508
2509         compiler.add(this, "node_geometry");
2510 }
2511
2512 /* TextureCoordinate */
2513
2514 TextureCoordinateNode::TextureCoordinateNode()
2515 : ShaderNode("texture_coordinate")
2516 {
2517         add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, ShaderInput::USE_OSL);
2518         add_output("Generated", SHADER_SOCKET_POINT);
2519         add_output("Normal", SHADER_SOCKET_NORMAL);
2520         add_output("UV", SHADER_SOCKET_POINT);
2521         add_output("Object", SHADER_SOCKET_POINT);
2522         add_output("Camera", SHADER_SOCKET_POINT);
2523         add_output("Window", SHADER_SOCKET_POINT);
2524         add_output("Reflection", SHADER_SOCKET_NORMAL);
2525
2526         from_dupli = false;
2527         use_transform = false;
2528         ob_tfm = transform_identity();
2529 }
2530
2531 void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attributes)
2532 {
2533         if(shader->has_surface) {
2534                 if(!from_dupli) {
2535                         if(!output("Generated")->links.empty())
2536                                 attributes->add(ATTR_STD_GENERATED);
2537                         if(!output("UV")->links.empty())
2538                                 attributes->add(ATTR_STD_UV);
2539                 }
2540         }
2541
2542         if(shader->has_volume) {
2543                 if(!from_dupli) {
2544                         if(!output("Generated")->links.empty()) {
2545                                 attributes->add(ATTR_STD_GENERATED_TRANSFORM);
2546                         }
2547                 }
2548         }
2549
2550         ShaderNode::attributes(shader, attributes);
2551 }
2552
2553 void TextureCoordinateNode::compile(SVMCompiler& compiler)
2554 {
2555         ShaderOutput *out;
2556         NodeType texco_node = NODE_TEX_COORD;
2557         NodeType attr_node = NODE_ATTR;
2558         NodeType geom_node = NODE_GEOMETRY;
2559
2560         if(bump == SHADER_BUMP_DX) {
2561                 texco_node = NODE_TEX_COORD_BUMP_DX;
2562                 attr_node = NODE_ATTR_BUMP_DX;
2563                 geom_node = NODE_GEOMETRY_BUMP_DX;
2564         }
2565         else if(bump == SHADER_BUMP_DY) {
2566                 texco_node = NODE_TEX_COORD_BUMP_DY;
2567                 attr_node = NODE_ATTR_BUMP_DY;
2568                 geom_node = NODE_GEOMETRY_BUMP_DY;
2569         }
2570         
2571         out = output("Generated");
2572         if(!out->links.empty()) {
2573                 if(compiler.background) {
2574                         compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out));
2575                 }
2576                 else {
2577                         if(from_dupli) {
2578                                 compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, compiler.stack_assign(out));
2579                         }
2580                         else if(compiler.output_type() == SHADER_TYPE_VOLUME) {
2581                                 compiler.add_node(texco_node, NODE_TEXCO_VOLUME_GENERATED, compiler.stack_assign(out));
2582                         }
2583                         else {
2584                                 int attr = compiler.attribute(ATTR_STD_GENERATED);
2585                                 compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
2586                         }
2587                 }
2588         }
2589
2590         out = output("Normal");
2591         if(!out->links.empty()) {
2592                 compiler.add_node(texco_node, NODE_TEXCO_NORMAL, compiler.stack_assign(out));
2593         }
2594
2595         out = output("UV");
2596         if(!out->links.empty()) {
2597                 if(from_dupli) {
2598                         compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
2599                 }
2600                 else {
2601                         int attr = compiler.attribute(ATTR_STD_UV);
2602                         compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
2603                 }
2604         }
2605
2606         out = output("Object");
2607         if(!out->links.empty()) {
2608                 compiler.add_node(texco_node, NODE_TEXCO_OBJECT, compiler.stack_assign(out), use_transform);
2609                 if(use_transform) {
2610                         Transform ob_itfm = transform_inverse(ob_tfm);
2611                         compiler.add_node(ob_itfm.x);
2612                         compiler.add_node(ob_itfm.y);
2613                         compiler.add_node(ob_itfm.z);
2614                         compiler.add_node(ob_itfm.w);
2615                 }
2616         }
2617
2618         out = output("Camera");
2619         if(!out->links.empty()) {
2620                 compiler.add_node(texco_node, NODE_TEXCO_CAMERA, compiler.stack_assign(out));
2621         }
2622
2623         out = output("Window");
2624         if(!out->links.empty()) {
2625                 compiler.add_node(texco_node, NODE_TEXCO_WINDOW, compiler.stack_assign(out));
2626         }
2627
2628         out = output("Reflection");
2629         if(!out->links.empty()) {
2630                 if(compiler.background) {
2631                         compiler.add_node(geom_node, NODE_GEOM_I, compiler.stack_assign(out));
2632                 }
2633                 else {
2634                         compiler.add_node(texco_node, NODE_TEXCO_REFLECTION, compiler.stack_assign(out));
2635                 }
2636         }
2637 }
2638
2639 void TextureCoordinateNode::compile(OSLCompiler& compiler)
2640 {
2641         if(bump == SHADER_BUMP_DX)
2642                 compiler.parameter("bump_offset", "dx");
2643         else if(bump == SHADER_BUMP_DY)
2644                 compiler.parameter("bump_offset", "dy");
2645         else
2646                 compiler.parameter("bump_offset", "center");
2647         
2648         if(compiler.background)
2649                 compiler.parameter("is_background", true);
2650         if(compiler.output_type() == SHADER_TYPE_VOLUME)
2651                 compiler.parameter("is_volume", true);
2652         compiler.parameter("use_transform", use_transform);
2653         Transform ob_itfm = transform_transpose(transform_inverse(ob_tfm));
2654         compiler.parameter("object_itfm", ob_itfm);
2655
2656         compiler.parameter("from_dupli", from_dupli);
2657
2658         compiler.add(this, "node_texture_coordinate");
2659 }
2660
2661 UVMapNode::UVMapNode()
2662 : ShaderNode("uvmap")
2663 {
2664         attribute = "";
2665         from_dupli = false;
2666
2667         add_output("UV", SHADER_SOCKET_POINT);
2668 }
2669
2670 void UVMapNode::attributes(Shader *shader, AttributeRequestSet *attributes)
2671 {
2672         if(shader->has_surface) {
2673                 if(!from_dupli) {
2674                         if(!output("UV")->links.empty()) {
2675                                 if(attribute != "")
2676                                         attributes->add(attribute);
2677                                 else
2678                                         attributes->add(ATTR_STD_UV);
2679                         }
2680                 }
2681         }
2682
2683         ShaderNode::attributes(shader, attributes);
2684 }
2685
2686 void UVMapNode::compile(SVMCompiler& compiler)
2687 {
2688         ShaderOutput *out = output("UV");
2689         NodeType texco_node = NODE_TEX_COORD;
2690         NodeType attr_node = NODE_ATTR;
2691         int attr;
2692
2693         if(bump == SHADER_BUMP_DX) {
2694                 texco_node = NODE_TEX_COORD_BUMP_DX;
2695                 attr_node = NODE_ATTR_BUMP_DX;
2696         }
2697         else if(bump == SHADER_BUMP_DY) {
2698                 texco_node = NODE_TEX_COORD_BUMP_DY;
2699                 attr_node = NODE_ATTR_BUMP_DY;
2700         }
2701
2702         if(!out->links.empty()) {
2703                 if(from_dupli) {
2704                         compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, compiler.stack_assign(out));
2705                 }
2706                 else {
2707                         if(attribute != "")
2708                                 attr = compiler.attribute(attribute);
2709                         else
2710                                 attr = compiler.attribute(ATTR_STD_UV);
2711
2712                         compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
2713                 }
2714         }
2715 }
2716
2717 void UVMapNode::compile(OSLCompiler& compiler)
2718 {
2719         if(bump == SHADER_BUMP_DX)
2720                 compiler.parameter("bump_offset", "dx");
2721         else if(bump == SHADER_BUMP_DY)
2722                 compiler.parameter("bump_offset", "dy");
2723         else
2724                 compiler.parameter("bump_offset", "center");
2725
2726         compiler.parameter("from_dupli", from_dupli);
2727         compiler.parameter("name", attribute.c_str());
2728         compiler.add(this, "node_uv_map");
2729 }
2730
2731 /* Light Path */
2732
2733 LightPathNode::LightPathNode()
2734 : ShaderNode("light_path")
2735 {
2736         add_output("Is Camera Ray", SHADER_SOCKET_FLOAT);
2737         add_output("Is Shadow Ray", SHADER_SOCKET_FLOAT);
2738         add_output("Is Diffuse Ray", SHADER_SOCKET_FLOAT);
2739         add_output("Is Glossy Ray", SHADER_SOCKET_FLOAT);
2740         add_output("Is Singular Ray", SHADER_SOCKET_FLOAT);
2741         add_output("Is Reflection Ray", SHADER_SOCKET_FLOAT);
2742         add_output("Is Transmission Ray", SHADER_SOCKET_FLOAT);
2743         add_output("Is Volume Scatter Ray", SHADER_SOCKET_FLOAT);
2744         add_output("Ray Length", SHADER_SOCKET_FLOAT);
2745         add_output("Ray Depth", SHADER_SOCKET_FLOAT);
2746         add_output("Transparent Depth", SHADER_SOCKET_FLOAT);
2747         add_output("Transmission Depth", SHADER_SOCKET_FLOAT);
2748 }
2749
2750 void LightPathNode::compile(SVMCompiler& compiler)
2751 {
2752         ShaderOutput *out;
2753
2754         out = output("Is Camera Ray");
2755         if(!out->links.empty()) {
2756                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_camera, compiler.stack_assign(out));
2757         }
2758
2759         out = output("Is Shadow Ray");
2760         if(!out->links.empty()) {
2761                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_shadow, compiler.stack_assign(out));
2762         }
2763
2764         out = output("Is Diffuse Ray");
2765         if(!out->links.empty()) {
2766                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_diffuse, compiler.stack_assign(out));
2767         }
2768
2769         out = output("Is Glossy Ray");
2770         if(!out->links.empty()) {
2771                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_glossy, compiler.stack_assign(out));
2772         }
2773
2774         out = output("Is Singular Ray");
2775         if(!out->links.empty()) {
2776                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_singular, compiler.stack_assign(out));
2777         }
2778
2779         out = output("Is Reflection Ray");
2780         if(!out->links.empty()) {
2781                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_reflection, compiler.stack_assign(out));
2782         }
2783
2784
2785         out = output("Is Transmission Ray");
2786         if(!out->links.empty()) {
2787                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, compiler.stack_assign(out));
2788         }
2789         
2790         out = output("Is Volume Scatter Ray");
2791         if(!out->links.empty()) {
2792                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_volume_scatter, compiler.stack_assign(out));
2793         }
2794
2795         out = output("Ray Length");
2796         if(!out->links.empty()) {
2797                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_length, compiler.stack_assign(out));
2798         }
2799         
2800         out = output("Ray Depth");
2801         if(!out->links.empty()) {
2802                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, compiler.stack_assign(out));
2803         }
2804
2805         out = output("Transparent Depth");
2806         if(!out->links.empty()) {
2807                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transparent, compiler.stack_assign(out));
2808         }
2809
2810         out = output("Transmission Depth");
2811         if(!out->links.empty()) {
2812                 compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_transmission, compiler.stack_assign(out));
2813         }
2814 }
2815
2816 void LightPathNode::compile(OSLCompiler& compiler)
2817 {
2818         compiler.add(this, "node_light_path");
2819 }
2820
2821 /* Light Falloff */
2822
2823 LightFalloffNode::LightFalloffNode()
2824 : ShaderNode("light_fallof")
2825 {
2826         add_input("Strength", SHADER_SOCKET_FLOAT, 100.0f);
2827         add_input("Smooth", SHADER_SOCKET_FLOAT, 0.0f);
2828         add_output("Quadratic", SHADER_SOCKET_FLOAT);
2829         add_output("Linear", SHADER_SOCKET_FLOAT);
2830         add_output("Constant", SHADER_SOCKET_FLOAT);
2831 }
2832
2833 void LightFalloffNode::compile(SVMCompiler& compiler)
2834 {
2835         ShaderInput *strength_in = input("Strength");
2836         ShaderInput *smooth_in = input("Smooth");
2837
2838         ShaderOutput *out = output("Quadratic");
2839         if(!out->links.empty()) {
2840                 compiler.add_node(NODE_LIGHT_FALLOFF, NODE_LIGHT_FALLOFF_QUADRATIC,
2841                         compiler.encode_uchar4(
2842                                 compiler.stack_assign(strength_in),
2843                                 compiler.stack_assign(smooth_in),
2844                                 compiler.stack_assign(out)));
2845         }
2846
2847         out = output("Linear");
2848         if(!out->links.empty()) {
2849                 compiler.add_node(NODE_LIGHT_FALLOFF, NODE_LIGHT_FALLOFF_LINEAR,
2850                         compiler.encode_uchar4(
2851                                 compiler.stack_assign(strength_in),
2852                                 compiler.stack_assign(smooth_in),
2853                                 compiler.stack_assign(out)));
2854         }
2855
2856         out = output("Constant");
2857         if(!out->links.empty()) {
2858                 compiler.add_node(NODE_LIGHT_FALLOFF, NODE_LIGHT_FALLOFF_CONSTANT,
2859                         compiler.encode_uchar4(
2860                                 compiler.stack_assign(strength_in),
2861                                 compiler.stack_assign(smooth_in),
2862                                 compiler.stack_assign(out)));
2863         }
2864 }
2865
2866 void LightFalloffNode::compile(OSLCompiler& compiler)
2867 {
2868         compiler.add(this, "node_light_falloff");
2869 }
2870
2871 /* Object Info */
2872
2873 ObjectInfoNode::ObjectInfoNode()
2874 : ShaderNode("object_info")
2875 {
2876         add_output("Location", SHADER_SOCKET_VECTOR);
2877         add_output("Object Index", SHADER_SOCKET_FLOAT);
2878         add_output("Material Index", SHADER_SOCKET_FLOAT);
2879         add_output("Random", SHADER_SOCKET_FLOAT);
2880 }
2881
2882 void ObjectInfoNode::compile(SVMCompiler& compiler)
2883 {
2884         ShaderOutput *out = output("Location");
2885         if(!out->links.empty()) {
2886                 compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_LOCATION, compiler.stack_assign(out));
2887         }
2888
2889         out = output("Object Index");
2890         if(!out->links.empty()) {
2891                 compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_INDEX, compiler.stack_assign(out));
2892         }
2893
2894         out = output("Material Index");
2895         if(!out->links.empty()) {
2896                 compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_MAT_INDEX, compiler.stack_assign(out));
2897         }
2898
2899         out = output("Random");
2900         if(!out->links.empty()) {
2901                 compiler.add_node(NODE_OBJECT_INFO, NODE_INFO_OB_RANDOM, compiler.stack_assign(out));
2902         }
2903 }
2904
2905 void ObjectInfoNode::compile(OSLCompiler& compiler)
2906 {
2907         compiler.add(this, "node_object_info");
2908 }
2909
2910 /* Particle Info */
2911
2912 ParticleInfoNode::ParticleInfoNode()
2913 : ShaderNode("particle_info")
2914 {
2915         add_output("Index", SHADER_SOCKET_FLOAT);
2916         add_output("Age", SHADER_SOCKET_FLOAT);
2917         add_output("Lifetime", SHADER_SOCKET_FLOAT);
2918         add_output("Location", SHADER_SOCKET_POINT);
2919 #if 0   /* not yet supported */
2920         add_output("Rotation", SHADER_SOCKET_QUATERNION);
2921 #endif
2922         add_output("Size", SHADER_SOCKET_FLOAT);
2923         add_output("Velocity", SHADER_SOCKET_VECTOR);
2924         add_output("Angular Velocity", SHADER_SOCKET_VECTOR);
2925 }
2926
2927 void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
2928 {
2929         if(!output("Index")->links.empty())
2930                 attributes->add(ATTR_STD_PARTICLE);
2931         if(!output("Age")->links.empty())
2932                 attributes->add(ATTR_STD_PARTICLE);
2933         if(!output("Lifetime")->links.empty())
2934                 attributes->add(ATTR_STD_PARTICLE);
2935         if(!output("Location")->links.empty())
2936                 attributes->add(ATTR_STD_PARTICLE);
2937 #if 0   /* not yet supported */
2938         if(!output("Rotation")->links.empty())
2939                 attributes->add(ATTR_STD_PARTICLE);
2940 #endif
2941         if(!output("Size")->links.empty())
2942                 attributes->add(ATTR_STD_PARTICLE);
2943         if(!output("Velocity")->links.empty())
2944                 attributes->add(ATTR_STD_PARTICLE);
2945         if(!output("Angular Velocity")->links.empty())
2946                 attributes->add(ATTR_STD_PARTICLE);
2947
2948         ShaderNode::attributes(shader, attributes);
2949 }
2950
2951 void ParticleInfoNode::compile(SVMCompiler& compiler)
2952 {
2953         ShaderOutput *out;
2954         
2955         out = output("Index");
2956         if(!out->links.empty()) {
2957                 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, compiler.stack_assign(out));
2958         }
2959         
2960         out = output("Age");
2961         if(!out->links.empty()) {
2962                 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_AGE, compiler.stack_assign(out));
2963         }
2964         
2965         out = output("Lifetime");
2966         if(!out->links.empty()) {
2967                 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, compiler.stack_assign(out));
2968         }
2969         
2970         out = output("Location");
2971         if(!out->links.empty()) {
2972                 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, compiler.stack_assign(out));
2973         }
2974         
2975         /* quaternion data is not yet supported by Cycles */
2976 #if 0
2977         out = output("Rotation");
2978         if(!out->links.empty()) {
2979                 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, compiler.stack_assign(out));
2980         }
2981 #endif
2982         
2983         out = output("Size");
2984         if(!out->links.empty()) {
2985                 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, compiler.stack_assign(out));
2986         }
2987         
2988         out = output("Velocity");
2989         if(!out->links.empty()) {
2990                 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_VELOCITY, compiler.stack_assign(out));
2991         }
2992         
2993         out = output("Angular Velocity");
2994         if(!out->links.empty()) {
2995                 compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ANGULAR_VELOCITY, compiler.stack_assign(out));
2996         }
2997 }
2998
2999 void ParticleInfoNode::compile(OSLCompiler& compiler)
3000 {
3001         compiler.add(this, "node_particle_info");
3002 }
3003
3004 /* Hair Info */
3005
3006 HairInfoNode::HairInfoNode()
3007 : ShaderNode("hair_info")
3008 {
3009         add_output("Is Strand", SHADER_SOCKET_FLOAT);
3010         add_output("Intercept", SHADER_SOCKET_FLOAT);
3011         add_output("Thickness", SHADER_SOCKET_FLOAT);
3012         add_output("Tangent Normal", SHADER_SOCKET_NORMAL);
3013         /*output for minimum hair width transparency - deactivated*/
3014         /*add_output("Fade", SHADER_SOCKET_FLOAT);*/
3015 }
3016
3017 void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
3018 {
3019         if(shader->has_surface) {
3020                 ShaderOutput *intercept_out = output("Intercept");
3021
3022                 if(!intercept_out->links.empty())
3023                         attributes->add(ATTR_STD_CURVE_INTERCEPT);
3024         }
3025
3026         ShaderNode::attributes(shader, attributes);
3027 }
3028
3029 void HairInfoNode::compile(SVMCompiler& compiler)
3030 {
3031         ShaderOutput *out;
3032         
3033         out = output("Is Strand");
3034         if(!out->links.empty()) {
3035                 compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_IS_STRAND, compiler.stack_assign(out));
3036         }
3037
3038         out = output("Intercept");
3039         if(!out->links.empty()) {
3040                 int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT);
3041                 compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT);
3042         }
3043
3044         out = output("Thickness");
3045         if(!out->links.empty()) {
3046                 compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_THICKNESS, compiler.stack_assign(out));
3047         }
3048
3049         out = output("Tangent Normal");
3050         if(!out->links.empty()) {
3051                 compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out));
3052         }
3053
3054         /*out = output("Fade");
3055         if(!out->links.empty()) {
3056                 compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out));
3057         }*/
3058
3059 }
3060
3061 void HairInfoNode::compile(OSLCompiler& compiler)
3062 {
3063         compiler.add(this, "node_hair_info");
3064 }
3065
3066 /* Value */
3067
3068 ValueNode::ValueNode()
3069 : ShaderNode("value")
3070 {
3071         value = 0.0f;
3072
3073         add_output("Value", SHADER_SOCKET_FLOAT);
3074 }
3075
3076 bool ValueNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/,
3077                               float3 *optimized_value)
3078 {
3079         *optimized_value = make_float3(value, value, value);
3080         return true;
3081 }
3082
3083 void ValueNode::compile(SVMCompiler& compiler)
3084 {
3085         ShaderOutput *val_out = output("Value");
3086
3087         compiler.add_node(NODE_VALUE_F, __float_as_int(value), compiler.stack_assign(val_out));
3088 }
3089
3090 void ValueNode::compile(OSLCompiler& compiler)
3091 {
3092         compiler.parameter("value_value", value);
3093         compiler.add(this, "node_value");
3094 }
3095
3096 /* Color */
3097
3098 ColorNode::ColorNode()
3099 : ShaderNode("color")
3100 {
3101         value = make_float3(0.0f, 0.0f, 0.0f);
3102
3103         add_output("Color", SHADER_SOCKET_COLOR);
3104 }
3105
3106 bool ColorNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/,
3107                               float3 *optimized_value)
3108 {
3109         *optimized_value = value;
3110         return true;
3111 }
3112
3113 void ColorNode::compile(SVMCompiler& compiler)
3114 {
3115         ShaderOutput *color_out = output("Color");
3116
3117         if(!color_out->links.empty()) {
3118                 compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
3119                 compiler.add_node(NODE_VALUE_V, value);
3120         }
3121 }
3122
3123 void ColorNode::compile(OSLCompiler& compiler)
3124 {
3125         compiler.parameter_color("color_value", value);
3126
3127         compiler.add(this, "node_value");
3128 }
3129
3130 /* Add Closure */
3131
3132 AddClosureNode::AddClosureNode()
3133 : ShaderNode("add_closure")
3134 {
3135         special_type = SHADER_SPECIAL_TYPE_COMBINE_CLOSURE;
3136
3137         add_input("Closure1", SHADER_SOCKET_CLOSURE);
3138         add_input("Closure2", SHADER_SOCKET_CLOSURE);
3139         add_output("Closure",  SHADER_SOCKET_CLOSURE);
3140 }
3141
3142 void AddClosureNode::compile(SVMCompiler& /*compiler*/)
3143 {
3144         /* handled in the SVM compiler */
3145 }
3146
3147 void AddClosureNode::compile(OSLCompiler& compiler)
3148 {
3149         compiler.add(this, "node_add_closure");
3150 }
3151
3152 /* Mix Closure */
3153
3154 MixClosureNode::MixClosureNode()
3155 : ShaderNode("mix_closure")
3156 {
3157         special_type = SHADER_SPECIAL_TYPE_COMBINE_CLOSURE;
3158
3159         add_input("Fac", SHADER_SOCKET_FLOAT, 0.5f);
3160         add_input("Closure1", SHADER_SOCKET_CLOSURE);
3161         add_input("Closure2", SHADER_SOCKET_CLOSURE);
3162         add_output("Closure",  SHADER_SOCKET_CLOSURE);
3163 }
3164
3165 void MixClosureNode::compile(SVMCompiler& /*compiler*/)
3166 {
3167         /* handled in the SVM compiler */
3168 }
3169
3170 void MixClosureNode::compile(OSLCompiler& compiler)
3171 {
3172         compiler.add(this, "node_mix_closure");
3173 }
3174
3175 bool MixClosureNode::constant_fold(ShaderGraph *graph, ShaderOutput * /*socket*/, float3 * /*optimized_value*/)
3176 {
3177         ShaderInput *fac_in = input("Fac");
3178         ShaderInput *closure1_in = input("Closure1");
3179         ShaderInput *closure2_in = input("Closure2");
3180         ShaderOutput *closure_out = output("Closure");
3181
3182         /* remove useless mix closures nodes */
3183         if(closure1_in->link == closure2_in->link) {
3184                 graph->relink(this, closure_out, closure1_in->link);
3185                 return true;
3186         }
3187
3188         /* remove unused mix closure input when factor is 0.0 or 1.0 */
3189         /* check for closure links and make sure factor link is disconnected */
3190         if(closure1_in->link && closure2_in->link && !fac_in->link) {
3191                 /* factor 0.0 */
3192                 if(fac_in->value.x == 0.0f) {
3193                         graph->relink(this, closure_out, closure1_in->link);
3194                         return true;
3195                 }
3196                 /* factor 1.0 */
3197                 else if(fac_in->value.x == 1.0f) {
3198                         graph->relink(this, closure_out, closure2_in->link);
3199                         return true;
3200                 }
3201         }
3202
3203         return false;
3204 }
3205
3206 /* Mix Closure */
3207
3208 MixClosureWeightNode::MixClosureWeightNode()
3209 : ShaderNode("mix_closure_weight")
3210 {
3211         add_input("Weight", SHADER_SOCKET_FLOAT, 1.0f);
3212         add_input("Fac", SHADER_SOCKET_FLOAT, 1.0f);
3213         add_output("Weight1", SHADER_SOCKET_FLOAT);
3214         add_output("Weight2", SHADER_SOCKET_FLOAT);
3215 }
3216
3217 void MixClosureWeightNode::compile(SVMCompiler& compiler)
3218 {
3219         ShaderInput *weight_in = input("Weight");
3220         ShaderInput *fac_in = input("Fac");
3221         ShaderOutput *weight1_out = output("Weight1");
3222         ShaderOutput *weight2_out = output("Weight2");
3223
3224         compiler.add_node(NODE_MIX_CLOSURE,
3225                 compiler.encode_uchar4(
3226                         compiler.stack_assign(fac_in),
3227                         compiler.stack_assign(weight_in),
3228                         compiler.stack_assign(weight1_out),
3229                         compiler.stack_assign(weight2_out)));
3230 }
3231
3232 void MixClosureWeightNode::compile(OSLCompiler& /*compiler*/)
3233 {
3234         assert(0);
3235 }
3236
3237 /* Invert */
3238
3239 InvertNode::InvertNode()
3240 : ShaderNode("invert")
3241 {
3242         add_input("Fac", SHADER_SOCKET_FLOAT, 1.0f);
3243         add_input("Color", SHADER_SOCKET_COLOR);
3244         add_output("Color",  SHADER_SOCKET_COLOR);
3245 }
3246
3247 void InvertNode::compile(SVMCompiler& compiler)
3248 {
3249         ShaderInput *fac_in = input("Fac");
3250         ShaderInput *color_in = input("Color");
3251         ShaderOutput *color_out = output("Color");
3252
3253         compiler.add_node(NODE_INVERT,
3254                 compiler.stack_assign(fac_in),
3255                 compiler.stack_assign(color_in),
3256                 compiler.stack_assign(color_out));
3257 }
3258
3259 void InvertNode::compile(OSLCompiler& compiler)
3260 {
3261         compiler.add(this, "node_invert");
3262 }
3263
3264 /* Mix */
3265
3266 MixNode::MixNode()
3267 : ShaderNode("mix")
3268 {
3269         type = ustring("Mix");
3270
3271         use_clamp = false;
3272
3273         add_input("Fac", SHADER_SOCKET_FLOAT, 0.5f);
3274         add_input("Color1", SHADER_SOCKET_COLOR);
3275         add_input("Color2", SHADER_SOCKET_COLOR);
3276         add_output("Color",  SHADER_SOCKET_COLOR);
3277 }
3278
3279 static ShaderEnum mix_type_init()
3280 {
3281         ShaderEnum enm;
3282
3283         enm.insert("Mix", NODE_MIX_BLEND);
3284         enm.insert("Add", NODE_MIX_ADD);
3285         enm.insert("Multiply", NODE_MIX_MUL);
3286         enm.insert("Screen", NODE_MIX_SCREEN);
3287         enm.insert("Overlay", NODE_MIX_OVERLAY);
3288         enm.insert("Subtract", NODE_MIX_SUB);
3289         enm.insert("Divide", NODE_MIX_DIV);
3290         enm.insert("Difference", NODE_MIX_DIFF);
3291         enm.insert("Darken", NODE_MIX_DARK);
3292         enm.insert("Lighten", NODE_MIX_LIGHT);
3293         enm.insert("Dodge", NODE_MIX_DODGE);
3294         enm.insert("Burn", NODE_MIX_BURN);
3295         enm.insert("Hue", NODE_MIX_HUE);
3296         enm.insert("Saturation", NODE_MIX_SAT);
3297         enm.insert("Value", NODE_MIX_VAL);
3298         enm.insert("Color", NODE_MIX_COLOR);
3299         enm.insert("Soft Light", NODE_MIX_SOFT);
3300         enm.insert("Linear Light", NODE_MIX_LINEAR);
3301
3302         return enm;
3303 }
3304
3305 ShaderEnum MixNode::type_enum = mix_type_init();
3306
3307 void MixNode::compile(SVMCompiler& compiler)
3308 {
3309         ShaderInput *fac_in = input("Fac");
3310         ShaderInput *color1_in = input("Color1");
3311         ShaderInput *color2_in = input("Color2");
3312         ShaderOutput *color_out = output("Color");
3313
3314         compiler.add_node(NODE_MIX,
3315                 compiler.stack_assign(fac_in),
3316                 compiler.stack_assign(color1_in),
3317                 compiler.stack_assign(color2_in));
3318         compiler.add_node(NODE_MIX, type_enum[type], compiler.stack_assign(color_out));
3319
3320         if(use_clamp) {
3321                 compiler.add_node(NODE_MIX, 0, compiler.stack_assign(color_out));
3322                 compiler.add_node(NODE_MIX, NODE_MIX_CLAMP, compiler.stack_assign(color_out));
3323         }
3324 }
3325
3326 void MixNode::compile(OSLCompiler& compiler)
3327 {
3328         compiler.parameter("type", type);
3329         compiler.parameter("Clamp", use_clamp);
3330         compiler.add(this, "node_mix");
3331 }
3332
3333 bool MixNode::constant_fold(ShaderGraph *graph, ShaderOutput * /*socket*/, float3 * optimized_value)
3334 {
3335         if(type != ustring("Mix")) {
3336                 return false;
3337         }
3338
3339         ShaderInput *fac_in = input("Fac");
3340         ShaderInput *color1_in = input("Color1");
3341         ShaderInput *color2_in = input("Color2");
3342         ShaderOutput *color_out = output("Color");
3343
3344         /* remove useless mix colors nodes */
3345         if(color1_in->link && color1_in->link == color2_in->link) {
3346                 graph->relink(this, color_out, color1_in->link);
3347                 return true;
3348         }
3349
3350         /* remove unused mix color input when factor is 0.0 or 1.0 */
3351         if(!fac_in->link) {
3352                 /* factor 0.0 */
3353                 if(fac_in->value.x == 0.0f) {
3354                         if (color1_in->link)
3355                                 graph->relink(this, color_out, color1_in->link);
3356                         else
3357                                 *optimized_value = color1_in->value;
3358                         return true;
3359                 }
3360                 /* factor 1.0 */
3361                 else if(fac_in->value.x == 1.0f) {
3362                         if (color2_in->link)
3363                                 graph->relink(this, color_out, color2_in->link);
3364                         else
3365                                 *optimized_value = color2_in->value;
3366                         return true;
3367                 }
3368         }
3369
3370         return false;
3371 }
3372
3373 /* Combine RGB */
3374 CombineRGBNode::CombineRGBNode()
3375 : ShaderNode("combine_rgb")
3376 {
3377         add_input("R", SHADER_SOCKET_FLOAT);
3378         add_input("G", SHADER_SOCKET_FLOAT);
3379         add_input("B", SHADER_SOCKET_FLOAT);
3380         add_output("Image", SHADER_SOCKET_COLOR);
3381 }
3382
3383 void CombineRGBNode::compile(SVMCompiler& compiler)
3384 {
3385         ShaderInput *red_in = input("R");
3386         ShaderInput *green_in = input("G");
3387         ShaderInput *blue_in = input("B");
3388         ShaderOutput *color_out = output("Image");
3389
3390         compiler.add_node(NODE_COMBINE_VECTOR,
3391                 compiler.stack_assign(red_in), 0,
3392                 compiler.stack_assign(color_out));
3393
3394         compiler.add_node(NODE_COMBINE_VECTOR,
3395                 compiler.stack_assign(green_in), 1,
3396                 compiler.stack_assign(color_out));
3397
3398         compiler.add_node(NODE_COMBINE_VECTOR,
3399                 compiler.stack_assign(blue_in), 2,
3400                 compiler.stack_assign(color_out));
3401 }
3402
3403 void CombineRGBNode::compile(OSLCompiler& compiler)
3404 {
3405         compiler.add(this, "node_combine_rgb");
3406 }
3407
3408 /* Combine XYZ */
3409 CombineXYZNode::CombineXYZNode()
3410 : ShaderNode("combine_xyz")
3411 {
3412         add_input("X", SHADER_SOCKET_FLOAT);
3413         add_input("Y", SHADER_SOCKET_FLOAT);
3414         add_input("Z", SHADER_SOCKET_FLOAT);
3415         add_output("Vector", SHADER_SOCKET_VECTOR);
3416 }
3417
3418 void CombineXYZNode::compile(SVMCompiler& compiler)
3419 {
3420         ShaderInput *x_in = input("X");
3421         ShaderInput *y_in = input("Y");
3422         ShaderInput *z_in = input("Z");
3423         ShaderOutput *vector_out = output("Vector");
3424
3425         compiler.add_node(NODE_COMBINE_VECTOR,
3426                 compiler.stack_assign(x_in), 0,
3427                 compiler.stack_assign(vector_out));
3428
3429         compiler.add_node(NODE_COMBINE_VECTOR,
3430                 compiler.stack_assign(y_in), 1,
3431                 compiler.stack_assign(vector_out));
3432
3433         compiler.add_node(NODE_COMBINE_VECTOR,
3434                 compiler.stack_assign(z_in), 2,
3435                 compiler.stack_assign(vector_out));
3436 }
3437
3438 void CombineXYZNode::compile(OSLCompiler& compiler)
3439 {
3440         compiler.add(this, "node_combine_xyz");
3441 }
3442
3443 /* Combine HSV */
3444 CombineHSVNode::CombineHSVNode()
3445 : ShaderNode("combine_hsv")
3446 {
3447         add_input("H", SHADER_SOCKET_FLOAT);
3448         add_input("S", SHADER_SOCKET_FLOAT);
3449         add_input("V", SHADER_SOCKET_FLOAT);
3450         add_output("Color", SHADER_SOCKET_COLOR);
3451 }
3452
3453 void CombineHSVNode::compile(SVMCompiler& compiler)
3454 {
3455         ShaderInput *hue_in = input("H");
3456         ShaderInput *saturation_in = input("S");
3457         ShaderInput *value_in = input("V");
3458         ShaderOutput *color_out = output("Color");
3459
3460         compiler.add_node(NODE_COMBINE_HSV,
3461                 compiler.stack_assign(hue_in),
3462                 compiler.stack_assign(saturation_in),
3463                 compiler.stack_assign(value_in));
3464         compiler.add_node(NODE_COMBINE_HSV,
3465                 compiler.stack_assign(color_out));
3466 }
3467
3468 void CombineHSVNode::compile(OSLCompiler& compiler)
3469 {
3470         compiler.add(this, "node_combine_hsv");
3471 }
3472
3473 /* Gamma */
3474 GammaNode::GammaNode()
3475 : ShaderNode("gamma")
3476 {
3477         add_input("Color", SHADER_SOCKET_COLOR);
3478         add_input("Gamma", SHADER_SOCKET_FLOAT);
3479         add_output("Color", SHADER_SOCKET_COLOR);
3480 }
3481
3482 bool GammaNode::constant_fold(ShaderGraph * /*graph*/, ShaderOutput *socket, float3 *optimized_value)
3483 {
3484         ShaderInput *color_in = input("Color");
3485         ShaderInput *gamma_in = input("Gamma");
3486
3487         if(socket == output("Color")) {
3488                 if(color_in->link == NULL && gamma_in->link == NULL) {
3489                         *optimized_value = svm_math_gamma_color(color_in->value,
3490                                                                 gamma_in->value.x);
3491                         return true;
3492                 }
3493         }
3494
3495         return false;
3496 }
3497
3498 void GammaNode::compile(SVMCompiler& compiler)
3499 {
3500         ShaderInput *color_in = input("Color");
3501         ShaderInput *gamma_in = input("Gamma");
3502         ShaderOutput *color_out = output("Color");
3503
3504         compiler.add_node(NODE_GAMMA,
3505                 compiler.stack_assign(gamma_in),
3506                 compiler.stack_assign(color_in),
3507                 compiler.stack_assign(color_out));
3508 }
3509
3510 void GammaNode::compile(OSLCompiler& compiler)
3511 {
3512         compiler.add(this, "node_gamma");
3513 }
3514
3515 /* Bright Contrast */
3516 BrightContrastNode::BrightContrastNode()
3517 : ShaderNode("brightness")
3518 {
3519         add_input("Color", SHADER_SOCKET_COLOR);
3520         add_input("Bright", SHADER_SOCKET_FLOAT);
3521         add_input("Contrast", SHADER_SOCKET_FLOAT);
3522         add_output("Color", SHADER_SOCKET_COLOR);
3523 }
3524
3525 void BrightContrastNode::compile(SVMCompiler& compiler)
3526 {
3527         ShaderInput *color_in = input("Color");
3528         ShaderInput *bright_in = input("Bright");
3529         ShaderInput *contrast_in = input("Contrast");
3530         ShaderOutput *color_out = output("Color");
3531
3532         compiler.add_node(NODE_BRIGHTCONTRAST,
3533                 compiler.stack_assign(color_in),
3534                 compiler.stack_assign(color_out),
3535                 compiler.encode_uchar4(
3536                         compiler.stack_assign(bright_in),
3537                         compiler.stack_assign(contrast_in)));
3538 }
3539
3540 void BrightContrastNode::compile(OSLCompiler& compiler)
3541 {
3542         compiler.add(this, "node_brightness");
3543 }
3544
3545 /* Separate RGB */
3546 SeparateRGBNode::SeparateRGBNode()
3547 : ShaderNode("separate_rgb")
3548 {
3549         add_input("Image", SHADER_SOCKET_COLOR);
3550         add_output("R", SHADER_SOCKET_FLOAT);
3551         add_output("G", SHADER_SOCKET_FLOAT);
3552         add_output("B", SHADER_SOCKET_FLOAT);
3553 }
3554
3555 void SeparateRGBNode::compile(SVMCompiler& compiler)
3556 {
3557         ShaderInput *color_in = input("Image");
3558         ShaderOutput *red_out = output("R");
3559         ShaderOutput *green_out = output("G");
3560         ShaderOutput *blue_out = output("B");
3561
3562         compiler.add_node(NODE_SEPARATE_VECTOR,
3563                 compiler.stack_assign(color_in), 0,
3564                 compiler.stack_assign(red_out));
3565
3566         compiler.add_node(NODE_SEPARATE_VECTOR,
3567                 compiler.stack_assign(color_in), 1,
3568                 compiler.stack_assign(green_out));
3569
3570         compiler.add_node(NODE_SEPARATE_VECTOR,
3571                 compiler.stack_assign(color_in), 2,
3572                 compiler.stack_assign(blue_out));
3573 }
3574
3575 void SeparateRGBNode::compile(OSLCompiler& compiler)
3576 {
3577         compiler.add(this, "node_separate_rgb");
3578 }
3579
3580 /* Separate XYZ */
3581 SeparateXYZNode::SeparateXYZNode()
3582 : ShaderNode("separate_xyz")
3583 {
3584         add_input("Vector", SHADER_SOCKET_VECTOR);
3585         add_output("X", SHADER_SOCKET_FLOAT);
3586         add_output("Y", SHADER_SOCKET_FLOAT);
3587         add_output("Z", SHADER_SOCKET_FLOAT);
3588 }
3589
3590 void SeparateXYZNode::compile(SVMCompiler& compiler)
3591 {
3592         ShaderInput *vector_in = input("Vector");
3593         ShaderOutput *x_out = output("X");
3594         ShaderOutput *y_out = output("Y");
3595         ShaderOutput *z_out = output("Z");
3596
3597         compiler.add_node(NODE_SEPARATE_VECTOR,
3598                 compiler.stack_assign(vector_in), 0,
3599                 compiler.stack_assign(x_out));
3600
3601         compiler.add_node(NODE_SEPARATE_VECTOR,