Blender V2.61 - r43446

nodes.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright 2011, Blender Foundation.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #include "image.h"
00020 #include "nodes.h"
00021 #include "svm.h"
00022 #include "osl.h"
00023 
00024 #include "util_transform.h"
00025 
00026 CCL_NAMESPACE_BEGIN
00027 
00028 /* Texture Mapping */
00029 
00030 TextureMapping::TextureMapping()
00031 {
00032     translation = make_float3(0.0f, 0.0f, 0.0f);
00033     rotation = make_float3(0.0f, 0.0f, 0.0f);
00034     scale = make_float3(1.0f, 1.0f, 1.0f);
00035 
00036     x_mapping = X;
00037     y_mapping = Y;
00038     z_mapping = Z;
00039 
00040     projection = FLAT;
00041 }
00042 
00043 Transform TextureMapping::compute_transform()
00044 {
00045     Transform mmat = transform_scale(make_float3(0.0f, 0.0f, 0.0f));
00046 
00047     if(x_mapping != NONE)
00048         mmat[0][x_mapping-1] = 1.0f;
00049     if(y_mapping != NONE)
00050         mmat[1][y_mapping-1] = 1.0f;
00051     if(z_mapping != NONE)
00052         mmat[2][z_mapping-1] = 1.0f;
00053 
00054     Transform smat = transform_scale(scale);
00055     Transform rmat = transform_euler(rotation);
00056     Transform tmat = transform_translate(translation);
00057 
00058     return tmat*rmat*smat*mmat;
00059 }
00060 
00061 bool TextureMapping::skip()
00062 {
00063     if(translation != make_float3(0.0f, 0.0f, 0.0f))
00064         return false;
00065     if(rotation != make_float3(0.0f, 0.0f, 0.0f))
00066         return false;
00067     if(scale != make_float3(1.0f, 1.0f, 1.0f))
00068         return false;
00069     
00070     if(x_mapping != X || y_mapping != Y || z_mapping != Z)
00071         return false;
00072     
00073     return true;
00074 }
00075 
00076 void TextureMapping::compile(SVMCompiler& compiler, int offset_in, int offset_out)
00077 {
00078     if(offset_in == SVM_STACK_INVALID || offset_out == SVM_STACK_INVALID)
00079         return;
00080 
00081     compiler.add_node(NODE_MAPPING, offset_in, offset_out);
00082 
00083     Transform tfm = compute_transform();
00084     compiler.add_node(tfm.x);
00085     compiler.add_node(tfm.y);
00086     compiler.add_node(tfm.z);
00087     compiler.add_node(tfm.w);
00088 }
00089 
00090 /* Image Texture */
00091 
00092 static ShaderEnum color_space_init()
00093 {
00094     ShaderEnum enm;
00095 
00096     enm.insert("Linear", 0);
00097     enm.insert("sRGB", 1);
00098 
00099     return enm;
00100 }
00101 
00102 ShaderEnum ImageTextureNode::color_space_enum = color_space_init();
00103 
00104 ImageTextureNode::ImageTextureNode()
00105 : TextureNode("image_texture")
00106 {
00107     image_manager = NULL;
00108     slot = -1;
00109     filename = "";
00110     color_space = ustring("sRGB");
00111 
00112     add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_UV);
00113     add_output("Color", SHADER_SOCKET_COLOR);
00114     add_output("Alpha", SHADER_SOCKET_FLOAT);
00115 }
00116 
00117 ImageTextureNode::~ImageTextureNode()
00118 {
00119     if(image_manager)
00120         image_manager->remove_image(filename);
00121 }
00122 
00123 ShaderNode *ImageTextureNode::clone() const
00124 {
00125     ImageTextureNode *node = new ImageTextureNode(*this);
00126     node->image_manager = NULL;
00127     node->slot = -1;
00128     return node;
00129 }
00130 
00131 void ImageTextureNode::compile(SVMCompiler& compiler)
00132 {
00133     ShaderInput *vector_in = input("Vector");
00134     ShaderOutput *color_out = output("Color");
00135     ShaderOutput *alpha_out = output("Alpha");
00136 
00137     image_manager = compiler.image_manager;
00138     if(slot == -1)
00139         slot = image_manager->add_image(filename);
00140 
00141     if(!color_out->links.empty())
00142         compiler.stack_assign(color_out);
00143     if(!alpha_out->links.empty())
00144         compiler.stack_assign(alpha_out);
00145 
00146     if(slot != -1) {
00147         compiler.stack_assign(vector_in);
00148 
00149         if(!tex_mapping.skip())
00150             tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
00151 
00152         compiler.add_node(NODE_TEX_IMAGE,
00153             slot,
00154             compiler.encode_uchar4(
00155                 vector_in->stack_offset,
00156                 color_out->stack_offset,
00157                 alpha_out->stack_offset,
00158                 color_space_enum[color_space]));
00159     }
00160     else {
00161         /* image not found */
00162         if(!color_out->links.empty()) {
00163             compiler.add_node(NODE_VALUE_V, color_out->stack_offset);
00164             compiler.add_node(NODE_VALUE_V, make_float3(0, 0, 0));
00165         }
00166         if(!alpha_out->links.empty())
00167             compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), alpha_out->stack_offset);
00168     }
00169 }
00170 
00171 void ImageTextureNode::compile(OSLCompiler& compiler)
00172 {
00173     compiler.parameter("filename", filename.c_str());
00174     compiler.parameter("color_space", color_space.c_str());
00175     compiler.add(this, "node_image_texture");
00176 }
00177 
00178 /* Environment Texture */
00179 
00180 ShaderEnum EnvironmentTextureNode::color_space_enum = color_space_init();
00181 
00182 EnvironmentTextureNode::EnvironmentTextureNode()
00183 : TextureNode("environment_texture")
00184 {
00185     image_manager = NULL;
00186     slot = -1;
00187     filename = "";
00188     color_space = ustring("sRGB");
00189 
00190     add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION);
00191     add_output("Color", SHADER_SOCKET_COLOR);
00192     add_output("Alpha", SHADER_SOCKET_FLOAT);
00193 }
00194 
00195 EnvironmentTextureNode::~EnvironmentTextureNode()
00196 {
00197     if(image_manager)
00198         image_manager->remove_image(filename);
00199 }
00200 
00201 ShaderNode *EnvironmentTextureNode::clone() const
00202 {
00203     EnvironmentTextureNode *node = new EnvironmentTextureNode(*this);
00204     node->image_manager = NULL;
00205     node->slot = -1;
00206     return node;
00207 }
00208 
00209 void EnvironmentTextureNode::compile(SVMCompiler& compiler)
00210 {
00211     ShaderInput *vector_in = input("Vector");
00212     ShaderOutput *color_out = output("Color");
00213     ShaderOutput *alpha_out = output("Alpha");
00214 
00215     image_manager = compiler.image_manager;
00216     if(slot == -1)
00217         slot = image_manager->add_image(filename);
00218 
00219     if(!color_out->links.empty())
00220         compiler.stack_assign(color_out);
00221     if(!alpha_out->links.empty())
00222         compiler.stack_assign(alpha_out);
00223 
00224     if(slot != -1) {
00225         compiler.stack_assign(vector_in);
00226 
00227         if(!tex_mapping.skip())
00228             tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
00229 
00230         compiler.add_node(NODE_TEX_ENVIRONMENT,
00231             slot,
00232             compiler.encode_uchar4(
00233                 vector_in->stack_offset,
00234                 color_out->stack_offset,
00235                 alpha_out->stack_offset,
00236                 color_space_enum[color_space]));
00237     }
00238     else {
00239         /* image not found */
00240         if(!color_out->links.empty()) {
00241             compiler.add_node(NODE_VALUE_V, color_out->stack_offset);
00242             compiler.add_node(NODE_VALUE_V, make_float3(0, 0, 0));
00243         }
00244         if(!alpha_out->links.empty())
00245             compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), alpha_out->stack_offset);
00246     }
00247 }
00248 
00249 void EnvironmentTextureNode::compile(OSLCompiler& compiler)
00250 {
00251     compiler.parameter("filename", filename.c_str());
00252     compiler.parameter("color_space", color_space.c_str());
00253     compiler.add(this, "node_environment_texture");
00254 }
00255 
00256 /* Sky Texture */
00257 
00258 static float2 sky_spherical_coordinates(float3 dir)
00259 {
00260     return make_float2(acosf(dir.z), atan2f(dir.x, dir.y));
00261 }
00262 
00263 static float sky_perez_function(float lam[6], float theta, float gamma)
00264 {
00265     return (1.f + lam[0]*expf(lam[1]/cosf(theta))) * (1.f + lam[2]*expf(lam[3]*gamma)  + lam[4]*cosf(gamma)*cosf(gamma));
00266 }
00267 
00268 static void sky_texture_precompute(KernelSunSky *ksunsky, float3 dir, float turbidity)
00269 {
00270     float2 spherical = sky_spherical_coordinates(dir);
00271     float theta = spherical.x;
00272     float phi = spherical.y;
00273 
00274     ksunsky->theta = theta;
00275     ksunsky->phi = phi;
00276 
00277     float theta2 = theta*theta;
00278     float theta3 = theta*theta*theta;
00279     float T = turbidity;
00280     float T2 = T * T;
00281 
00282     float chi = (4.0f / 9.0f - T / 120.0f) * (M_PI_F - 2.0f * theta);
00283     ksunsky->zenith_Y = (4.0453f * T - 4.9710f) * tan(chi) - 0.2155f * T + 2.4192f;
00284     ksunsky->zenith_Y *= 0.06f;
00285 
00286     ksunsky->zenith_x =
00287     (0.00166f * theta3 - 0.00375f * theta2 + 0.00209f * theta) * T2 +
00288     (-0.02903f * theta3 + 0.06377f * theta2 - 0.03202f * theta + 0.00394f) * T +
00289     (0.11693f * theta3 - 0.21196f * theta2 + 0.06052f * theta + 0.25886f);
00290 
00291     ksunsky->zenith_y =
00292     (0.00275f * theta3 - 0.00610f * theta2 + 0.00317f * theta) * T2 +
00293     (-0.04214f * theta3 + 0.08970f * theta2 - 0.04153f * theta  + 0.00516f) * T +
00294     (0.15346f * theta3 - 0.26756f * theta2 + 0.06670f * theta  + 0.26688f);
00295 
00296     ksunsky->perez_Y[0] = (0.1787f * T  - 1.4630f);
00297     ksunsky->perez_Y[1] = (-0.3554f * T  + 0.4275f);
00298     ksunsky->perez_Y[2] = (-0.0227f * T  + 5.3251f);
00299     ksunsky->perez_Y[3] = (0.1206f * T  - 2.5771f);
00300     ksunsky->perez_Y[4] = (-0.0670f * T  + 0.3703f);
00301 
00302     ksunsky->perez_x[0] = (-0.0193f * T  - 0.2592f);
00303     ksunsky->perez_x[1] = (-0.0665f * T  + 0.0008f);
00304     ksunsky->perez_x[2] = (-0.0004f * T  + 0.2125f);
00305     ksunsky->perez_x[3] = (-0.0641f * T  - 0.8989f);
00306     ksunsky->perez_x[4] = (-0.0033f * T  + 0.0452f);
00307 
00308     ksunsky->perez_y[0] = (-0.0167f * T  - 0.2608f);
00309     ksunsky->perez_y[1] = (-0.0950f * T  + 0.0092f);
00310     ksunsky->perez_y[2] = (-0.0079f * T  + 0.2102f);
00311     ksunsky->perez_y[3] = (-0.0441f * T  - 1.6537f);
00312     ksunsky->perez_y[4] = (-0.0109f * T  + 0.0529f);
00313 
00314     ksunsky->zenith_Y /= sky_perez_function(ksunsky->perez_Y, 0, theta);
00315     ksunsky->zenith_x /= sky_perez_function(ksunsky->perez_x, 0, theta);
00316     ksunsky->zenith_y /= sky_perez_function(ksunsky->perez_y, 0, theta);
00317 }
00318 
00319 SkyTextureNode::SkyTextureNode()
00320 : TextureNode("sky_texture")
00321 {
00322     sun_direction = make_float3(0.0f, 0.0f, 1.0f);
00323     turbidity = 2.2f;
00324 
00325     add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION);
00326     add_output("Color", SHADER_SOCKET_COLOR);
00327 }
00328 
00329 void SkyTextureNode::compile(SVMCompiler& compiler)
00330 {
00331     ShaderInput *vector_in = input("Vector");
00332     ShaderOutput *color_out = output("Color");
00333 
00334     if(compiler.sunsky) {
00335         sky_texture_precompute(compiler.sunsky, sun_direction, turbidity);
00336         compiler.sunsky = NULL;
00337     }
00338 
00339     if(vector_in->link)
00340         compiler.stack_assign(vector_in);
00341     if(!tex_mapping.skip())
00342         tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
00343 
00344     compiler.stack_assign(color_out);
00345     compiler.add_node(NODE_TEX_SKY, vector_in->stack_offset, color_out->stack_offset);
00346 }
00347 
00348 void SkyTextureNode::compile(OSLCompiler& compiler)
00349 {
00350     compiler.parameter_vector("sun_direction", sun_direction);
00351     compiler.parameter("turbidity", turbidity);
00352     compiler.add(this, "node_sky_texture");
00353 }
00354 
00355 /* Gradient Texture */
00356 
00357 static ShaderEnum gradient_type_init()
00358 {
00359     ShaderEnum enm;
00360 
00361     enm.insert("Linear", NODE_BLEND_LINEAR);
00362     enm.insert("Quadratic", NODE_BLEND_QUADRATIC);
00363     enm.insert("Easing", NODE_BLEND_EASING);
00364     enm.insert("Diagonal", NODE_BLEND_DIAGONAL);
00365     enm.insert("Radial", NODE_BLEND_RADIAL);
00366     enm.insert("Quadratic Sphere", NODE_BLEND_QUADRATIC_SPHERE);
00367     enm.insert("Spherical", NODE_BLEND_SPHERICAL);
00368 
00369     return enm;
00370 }
00371 
00372 ShaderEnum GradientTextureNode::type_enum = gradient_type_init();
00373 
00374 GradientTextureNode::GradientTextureNode()
00375 : TextureNode("gradient_texture")
00376 {
00377     type = ustring("Linear");
00378 
00379     add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
00380     add_output("Color", SHADER_SOCKET_COLOR);
00381     add_output("Fac", SHADER_SOCKET_FLOAT);
00382 }
00383 
00384 void GradientTextureNode::compile(SVMCompiler& compiler)
00385 {
00386     ShaderInput *vector_in = input("Vector");
00387     ShaderOutput *color_out = output("Color");
00388     ShaderOutput *fac_out = output("Fac");
00389 
00390     if(vector_in->link) compiler.stack_assign(vector_in);
00391 
00392     if(!tex_mapping.skip())
00393         tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
00394 
00395     if(!fac_out->links.empty())
00396         compiler.stack_assign(fac_out);
00397     if(!color_out->links.empty())
00398         compiler.stack_assign(color_out);
00399 
00400     compiler.add_node(NODE_TEX_GRADIENT,
00401         compiler.encode_uchar4(type_enum[type], vector_in->stack_offset, fac_out->stack_offset, color_out->stack_offset));
00402 }
00403 
00404 void GradientTextureNode::compile(OSLCompiler& compiler)
00405 {
00406     compiler.parameter("Type", type);
00407     compiler.add(this, "node_gradient_texture");
00408 }
00409 
00410 /* Noise Texture */
00411 
00412 NoiseTextureNode::NoiseTextureNode()
00413 : TextureNode("noise_texture")
00414 {
00415     add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
00416     add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f);
00417     add_input("Detail", SHADER_SOCKET_FLOAT, 2.0f);
00418     add_input("Distortion", SHADER_SOCKET_FLOAT, 0.0f);
00419 
00420     add_output("Color", SHADER_SOCKET_COLOR);
00421     add_output("Fac", SHADER_SOCKET_FLOAT);
00422 }
00423 
00424 void NoiseTextureNode::compile(SVMCompiler& compiler)
00425 {
00426     ShaderInput *distortion_in = input("Distortion");
00427     ShaderInput *detail_in = input("Detail");
00428     ShaderInput *scale_in = input("Scale");
00429     ShaderInput *vector_in = input("Vector");
00430     ShaderOutput *color_out = output("Color");
00431     ShaderOutput *fac_out = output("Fac");
00432 
00433     if(vector_in->link) compiler.stack_assign(vector_in);
00434     if(scale_in->link) compiler.stack_assign(scale_in);
00435     if(detail_in->link) compiler.stack_assign(detail_in);
00436     if(distortion_in->link) compiler.stack_assign(distortion_in);
00437 
00438     if(!tex_mapping.skip())
00439         tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
00440 
00441     if(!fac_out->links.empty())
00442         compiler.stack_assign(fac_out);
00443     if(!color_out->links.empty())
00444         compiler.stack_assign(color_out);
00445 
00446     compiler.add_node(NODE_TEX_NOISE,
00447         compiler.encode_uchar4(vector_in->stack_offset, scale_in->stack_offset, detail_in->stack_offset, distortion_in->stack_offset),
00448         compiler.encode_uchar4(color_out->stack_offset, fac_out->stack_offset));
00449     compiler.add_node(
00450         __float_as_int(scale_in->value.x),
00451         __float_as_int(detail_in->value.x),
00452         __float_as_int(distortion_in->value.x));
00453 }
00454 
00455 void NoiseTextureNode::compile(OSLCompiler& compiler)
00456 {
00457     compiler.add(this, "node_noise_texture");
00458 }
00459 
00460 /* Voronoi Texture */
00461 
00462 static ShaderEnum voronoi_coloring_init()
00463 {
00464     ShaderEnum enm;
00465 
00466     enm.insert("Intensity", NODE_VORONOI_INTENSITY);
00467     enm.insert("Cells", NODE_VORONOI_CELLS);
00468 
00469     return enm;
00470 }
00471 
00472 ShaderEnum VoronoiTextureNode::coloring_enum  = voronoi_coloring_init();
00473 
00474 VoronoiTextureNode::VoronoiTextureNode()
00475 : TextureNode("voronoi_texture")
00476 {
00477     coloring = ustring("Intensity");
00478 
00479     add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f);
00480     add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
00481 
00482     add_output("Color", SHADER_SOCKET_COLOR);
00483     add_output("Fac", SHADER_SOCKET_FLOAT);
00484 }
00485 
00486 void VoronoiTextureNode::compile(SVMCompiler& compiler)
00487 {
00488     ShaderInput *scale_in = input("Scale");
00489     ShaderInput *vector_in = input("Vector");
00490     ShaderOutput *color_out = output("Color");
00491     ShaderOutput *fac_out = output("Fac");
00492 
00493     if(vector_in->link) compiler.stack_assign(vector_in);
00494     if(scale_in->link) compiler.stack_assign(scale_in);
00495 
00496     if(!tex_mapping.skip())
00497         tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
00498 
00499     compiler.stack_assign(color_out);
00500     compiler.stack_assign(fac_out);
00501 
00502     compiler.add_node(NODE_TEX_VORONOI,
00503         coloring_enum[coloring],
00504         compiler.encode_uchar4(scale_in->stack_offset, vector_in->stack_offset, fac_out->stack_offset, color_out->stack_offset),
00505         __float_as_int(scale_in->value.x));
00506 }
00507 
00508 void VoronoiTextureNode::compile(OSLCompiler& compiler)
00509 {
00510     compiler.parameter("Coloring", coloring);
00511     compiler.add(this, "node_voronoi_texture");
00512 }
00513 
00514 /* Musgrave Texture */
00515 
00516 static ShaderEnum musgrave_type_init()
00517 {
00518     ShaderEnum enm;
00519 
00520     enm.insert("Multifractal", NODE_MUSGRAVE_MULTIFRACTAL);
00521     enm.insert("fBM", NODE_MUSGRAVE_FBM);
00522     enm.insert("Hybrid Multifractal", NODE_MUSGRAVE_HYBRID_MULTIFRACTAL);
00523     enm.insert("Ridged Multifractal", NODE_MUSGRAVE_RIDGED_MULTIFRACTAL);
00524     enm.insert("Hetero Terrain", NODE_MUSGRAVE_HETERO_TERRAIN);
00525 
00526     return enm;
00527 }
00528 
00529 ShaderEnum MusgraveTextureNode::type_enum = musgrave_type_init();
00530 
00531 MusgraveTextureNode::MusgraveTextureNode()
00532 : TextureNode("musgrave_texture")
00533 {
00534     type = ustring("fBM");
00535 
00536     add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f);
00537     add_input("Detail", SHADER_SOCKET_FLOAT, 2.0f);
00538     add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
00539     add_input("Dimension", SHADER_SOCKET_FLOAT, 2.0f);
00540     add_input("Lacunarity", SHADER_SOCKET_FLOAT, 1.0f);
00541     add_input("Offset", SHADER_SOCKET_FLOAT, 0.0f);
00542     add_input("Gain", SHADER_SOCKET_FLOAT, 1.0f);
00543 
00544     add_output("Fac", SHADER_SOCKET_FLOAT);
00545     add_output("Color", SHADER_SOCKET_COLOR);
00546 }
00547 
00548 void MusgraveTextureNode::compile(SVMCompiler& compiler)
00549 {
00550     ShaderInput *vector_in = input("Vector");
00551     ShaderInput *scale_in = input("Scale");
00552     ShaderInput *dimension_in = input("Dimension");
00553     ShaderInput *lacunarity_in = input("Lacunarity");
00554     ShaderInput *detail_in = input("Detail");
00555     ShaderInput *offset_in = input("Offset");
00556     ShaderInput *gain_in = input("Gain");
00557     ShaderOutput *fac_out = output("Fac");
00558     ShaderOutput *color_out = output("Color");
00559 
00560     if(vector_in->link) compiler.stack_assign(vector_in);
00561     if(dimension_in->link) compiler.stack_assign(dimension_in);
00562     if(lacunarity_in->link) compiler.stack_assign(lacunarity_in);
00563     if(detail_in->link) compiler.stack_assign(detail_in);
00564     if(offset_in->link) compiler.stack_assign(offset_in);
00565     if(gain_in->link) compiler.stack_assign(gain_in);
00566     if(scale_in->link) compiler.stack_assign(scale_in);
00567 
00568     if(!tex_mapping.skip())
00569         tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
00570 
00571     if(!fac_out->links.empty())
00572         compiler.stack_assign(fac_out);
00573     if(!color_out->links.empty())
00574         compiler.stack_assign(color_out);
00575 
00576     compiler.add_node(NODE_TEX_MUSGRAVE,
00577         compiler.encode_uchar4(type_enum[type], vector_in->stack_offset, color_out->stack_offset, fac_out->stack_offset),
00578         compiler.encode_uchar4(dimension_in->stack_offset, lacunarity_in->stack_offset, detail_in->stack_offset, offset_in->stack_offset),
00579         compiler.encode_uchar4(gain_in->stack_offset, scale_in->stack_offset));
00580     compiler.add_node(__float_as_int(dimension_in->value.x),
00581         __float_as_int(lacunarity_in->value.x),
00582         __float_as_int(detail_in->value.x),
00583         __float_as_int(offset_in->value.x));
00584     compiler.add_node(__float_as_int(gain_in->value.x),
00585         __float_as_int(scale_in->value.x));
00586 }
00587 
00588 void MusgraveTextureNode::compile(OSLCompiler& compiler)
00589 {
00590     compiler.parameter("Type", type);
00591 
00592     compiler.add(this, "node_musgrave_texture");
00593 }
00594 
00595 /* Wave Texture */
00596 
00597 static ShaderEnum wave_type_init()
00598 {
00599     ShaderEnum enm;
00600 
00601     enm.insert("Bands", NODE_WAVE_BANDS);
00602     enm.insert("Rings", NODE_WAVE_RINGS);
00603 
00604     return enm;
00605 }
00606 
00607 ShaderEnum WaveTextureNode::type_enum = wave_type_init();
00608 
00609 WaveTextureNode::WaveTextureNode()
00610 : TextureNode("marble_texture")
00611 {
00612     type = ustring("Bands");
00613 
00614     add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f);
00615     add_input("Distortion", SHADER_SOCKET_FLOAT, 0.0f);
00616     add_input("Detail", SHADER_SOCKET_FLOAT, 2.0f);
00617     add_input("Detail Scale", SHADER_SOCKET_FLOAT, 1.0f);
00618     add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
00619 
00620     add_output("Color", SHADER_SOCKET_COLOR);
00621     add_output("Fac", SHADER_SOCKET_FLOAT);
00622 }
00623 
00624 void WaveTextureNode::compile(SVMCompiler& compiler)
00625 {
00626     ShaderInput *scale_in = input("Scale");
00627     ShaderInput *distortion_in = input("Distortion");
00628     ShaderInput *dscale_in = input("Detail Scale");
00629     ShaderInput *detail_in = input("Detail");
00630     ShaderInput *vector_in = input("Vector");
00631     ShaderOutput *fac_out = output("Fac");
00632     ShaderOutput *color_out = output("Color");
00633 
00634     if(scale_in->link) compiler.stack_assign(scale_in);
00635     if(detail_in->link) compiler.stack_assign(detail_in);
00636     if(distortion_in->link) compiler.stack_assign(distortion_in);
00637     if(dscale_in->link) compiler.stack_assign(dscale_in);
00638     if(vector_in->link) compiler.stack_assign(vector_in);
00639 
00640     if(!tex_mapping.skip())
00641         tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
00642 
00643     if(!fac_out->links.empty())
00644         compiler.stack_assign(fac_out);
00645     if(!color_out->links.empty())
00646         compiler.stack_assign(color_out);
00647 
00648     compiler.add_node(NODE_TEX_WAVE,
00649         compiler.encode_uchar4(type_enum[type], color_out->stack_offset, fac_out->stack_offset, dscale_in->stack_offset),
00650         compiler.encode_uchar4(vector_in->stack_offset, scale_in->stack_offset, detail_in->stack_offset, distortion_in->stack_offset));
00651 
00652     compiler.add_node(
00653         __float_as_int(scale_in->value.x),
00654         __float_as_int(detail_in->value.x),
00655         __float_as_int(distortion_in->value.x),
00656         __float_as_int(dscale_in->value.x));
00657 }
00658 
00659 void WaveTextureNode::compile(OSLCompiler& compiler)
00660 {
00661     compiler.parameter("Type", type);
00662 
00663     compiler.add(this, "node_marble_texture");
00664 }
00665 
00666 /* Magic Texture */
00667 
00668 MagicTextureNode::MagicTextureNode()
00669 : TextureNode("magic_texture")
00670 {
00671     depth = 2;
00672 
00673     add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
00674     add_input("Scale", SHADER_SOCKET_FLOAT, 5.0f);
00675     add_input("Distortion", SHADER_SOCKET_FLOAT, 1.0f);
00676 
00677     add_output("Color", SHADER_SOCKET_COLOR);
00678     add_output("Fac", SHADER_SOCKET_FLOAT);
00679 }
00680 
00681 void MagicTextureNode::compile(SVMCompiler& compiler)
00682 {
00683     ShaderInput *vector_in = input("Vector");
00684     ShaderInput *scale_in = input("Scale");
00685     ShaderInput *distortion_in = input("Distortion");
00686     ShaderOutput *color_out = output("Color");
00687     ShaderOutput *fac_out = output("Fac");
00688 
00689     if(vector_in->link) compiler.stack_assign(vector_in);
00690     if(distortion_in->link) compiler.stack_assign(distortion_in);
00691     if(scale_in->link) compiler.stack_assign(scale_in);
00692 
00693     if(!tex_mapping.skip())
00694         tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
00695 
00696     if(!fac_out->links.empty())
00697         compiler.stack_assign(fac_out);
00698     if(!color_out->links.empty())
00699         compiler.stack_assign(color_out);
00700 
00701     compiler.add_node(NODE_TEX_MAGIC,
00702         compiler.encode_uchar4(depth, color_out->stack_offset, fac_out->stack_offset),
00703         compiler.encode_uchar4(vector_in->stack_offset, scale_in->stack_offset, distortion_in->stack_offset));
00704     compiler.add_node(
00705         __float_as_int(scale_in->value.x),
00706         __float_as_int(distortion_in->value.x));
00707 }
00708 
00709 void MagicTextureNode::compile(OSLCompiler& compiler)
00710 {
00711     compiler.parameter("Depth", depth);
00712     compiler.add(this, "node_magic_texture");
00713 }
00714 
00715 /* Checker Texture */
00716 
00717 CheckerTextureNode::CheckerTextureNode()
00718 : TextureNode("checker_texture")
00719 {
00720     add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::TEXTURE_GENERATED);
00721     add_input("Color1", SHADER_SOCKET_COLOR);
00722     add_input("Color2", SHADER_SOCKET_COLOR);
00723     add_input("Scale", SHADER_SOCKET_FLOAT, 1.0f);
00724 
00725     add_output("Color", SHADER_SOCKET_COLOR);
00726     add_output("Fac", SHADER_SOCKET_FLOAT);
00727 }
00728 
00729 void CheckerTextureNode::compile(SVMCompiler& compiler)
00730 {
00731     ShaderInput *vector_in = input("Vector");
00732     ShaderInput *color1_in = input("Color1");
00733     ShaderInput *color2_in = input("Color2");
00734     ShaderInput *scale_in = input("Scale");
00735     
00736     ShaderOutput *color_out = output("Color");
00737     ShaderOutput *fac_out = output("Fac");
00738 
00739     compiler.stack_assign(vector_in);
00740     compiler.stack_assign(color1_in);
00741     compiler.stack_assign(color2_in);
00742     if(scale_in->link) compiler.stack_assign(scale_in);
00743 
00744     if(!tex_mapping.skip())
00745         tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
00746 
00747     if(!color_out->links.empty())
00748         compiler.stack_assign(color_out);
00749     if(!fac_out->links.empty())
00750         compiler.stack_assign(fac_out);
00751 
00752     compiler.add_node(NODE_TEX_CHECKER,
00753         compiler.encode_uchar4(vector_in->stack_offset, color1_in->stack_offset, color2_in->stack_offset, scale_in->stack_offset),
00754         compiler.encode_uchar4(color_out->stack_offset, fac_out->stack_offset),
00755         __float_as_int(scale_in->value.x));
00756 }
00757 
00758 void CheckerTextureNode::compile(OSLCompiler& compiler)
00759 {
00760     compiler.add(this, "node_checker_texture");
00761 }
00762 
00763 /* Normal */
00764 
00765 NormalNode::NormalNode()
00766 : ShaderNode("normal")
00767 {
00768     direction = make_float3(0.0f, 0.0f, 1.0f);
00769 
00770     add_input("Normal", SHADER_SOCKET_NORMAL);
00771     add_output("Normal", SHADER_SOCKET_NORMAL);
00772     add_output("Dot",  SHADER_SOCKET_FLOAT);
00773 }
00774 
00775 void NormalNode::compile(SVMCompiler& compiler)
00776 {
00777     ShaderInput *normal_in = input("Normal");
00778     ShaderOutput *normal_out = output("Normal");
00779     ShaderOutput *dot_out = output("Dot");
00780 
00781     compiler.stack_assign(normal_in);
00782     compiler.stack_assign(normal_out);
00783     compiler.stack_assign(dot_out);
00784 
00785     compiler.add_node(NODE_NORMAL, normal_in->stack_offset, normal_out->stack_offset, dot_out->stack_offset);
00786     compiler.add_node(
00787         __float_as_int(direction.x),
00788         __float_as_int(direction.y),
00789         __float_as_int(direction.z));
00790 }
00791 
00792 void NormalNode::compile(OSLCompiler& compiler)
00793 {
00794     compiler.parameter_vector("Direction", direction);
00795     compiler.add(this, "node_normal");
00796 }
00797 
00798 /* Mapping */
00799 
00800 MappingNode::MappingNode()
00801 : ShaderNode("mapping")
00802 {
00803     add_input("Vector", SHADER_SOCKET_POINT);
00804     add_output("Vector", SHADER_SOCKET_POINT);
00805 }
00806 
00807 void MappingNode::compile(SVMCompiler& compiler)
00808 {
00809     ShaderInput *vector_in = input("Vector");
00810     ShaderOutput *vector_out = output("Vector");
00811 
00812     compiler.stack_assign(vector_in);
00813     compiler.stack_assign(vector_out);
00814 
00815     tex_mapping.compile(compiler, vector_in->stack_offset, vector_out->stack_offset);
00816 }
00817 
00818 void MappingNode::compile(OSLCompiler& compiler)
00819 {
00820     Transform tfm = transform_transpose(tex_mapping.compute_transform());
00821     compiler.parameter("Matrix", tfm);
00822 
00823     compiler.add(this, "node_mapping");
00824 }
00825 
00826 /* Convert */
00827 
00828 ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
00829 : ShaderNode("convert")
00830 {
00831     from = from_;
00832     to = to_;
00833 
00834     assert(from != to);
00835 
00836     if(from == SHADER_SOCKET_FLOAT)
00837         add_input("Val", SHADER_SOCKET_FLOAT);
00838     else if(from == SHADER_SOCKET_COLOR)
00839         add_input("Color", SHADER_SOCKET_COLOR);
00840     else if(from == SHADER_SOCKET_VECTOR)
00841         add_input("Vector", SHADER_SOCKET_VECTOR);
00842     else if(from == SHADER_SOCKET_POINT)
00843         add_input("Point", SHADER_SOCKET_POINT);
00844     else if(from == SHADER_SOCKET_NORMAL)
00845         add_input("Normal", SHADER_SOCKET_NORMAL);
00846     else
00847         assert(0);
00848 
00849     if(to == SHADER_SOCKET_FLOAT)
00850         add_output("Val", SHADER_SOCKET_FLOAT);
00851     else if(to == SHADER_SOCKET_COLOR)
00852         add_output("Color", SHADER_SOCKET_COLOR);
00853     else if(to == SHADER_SOCKET_VECTOR)
00854         add_output("Vector", SHADER_SOCKET_VECTOR);
00855     else if(to == SHADER_SOCKET_POINT)
00856         add_output("Point", SHADER_SOCKET_POINT);
00857     else if(to == SHADER_SOCKET_NORMAL)
00858         add_output("Normal", SHADER_SOCKET_NORMAL);
00859     else
00860         assert(0);
00861 }
00862 
00863 void ConvertNode::compile(SVMCompiler& compiler)
00864 {
00865     ShaderInput *in = inputs[0];
00866     ShaderOutput *out = outputs[0];
00867 
00868     if(to == SHADER_SOCKET_FLOAT) {
00869         compiler.stack_assign(in);
00870         compiler.stack_assign(out);
00871 
00872         if(from == SHADER_SOCKET_COLOR)
00873             /* color to float */
00874             compiler.add_node(NODE_CONVERT, NODE_CONVERT_CF, in->stack_offset, out->stack_offset);
00875         else
00876             /* vector/point/normal to float */
00877             compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, in->stack_offset, out->stack_offset);
00878     }
00879     else if(from == SHADER_SOCKET_FLOAT) {
00880         compiler.stack_assign(in);
00881         compiler.stack_assign(out);
00882 
00883         /* float to float3 */
00884         compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset);
00885     }
00886     else {
00887         /* float3 to float3 */
00888         if(in->link) {
00889             /* no op in SVM */
00890             compiler.stack_link(in, out);
00891         }
00892         else {
00893             /* set 0,0,0 value */
00894             compiler.stack_assign(in);
00895             compiler.stack_assign(out);
00896 
00897             compiler.add_node(NODE_VALUE_V, in->stack_offset);
00898             compiler.add_node(NODE_VALUE_V, in->value);
00899         }
00900     }
00901 }
00902 
00903 void ConvertNode::compile(OSLCompiler& compiler)
00904 {
00905     if(from == SHADER_SOCKET_FLOAT)
00906         compiler.add(this, "node_convert_from_float");
00907     else if(from == SHADER_SOCKET_COLOR)
00908         compiler.add(this, "node_convert_from_color");
00909     else if(from == SHADER_SOCKET_VECTOR)
00910         compiler.add(this, "node_convert_from_vector");
00911     else if(from == SHADER_SOCKET_POINT)
00912         compiler.add(this, "node_convert_from_point");
00913     else if(from == SHADER_SOCKET_NORMAL)
00914         compiler.add(this, "node_convert_from_normal");
00915     else
00916         assert(0);
00917 }
00918 
00919 /* Proxy */
00920 
00921 ProxyNode::ProxyNode(ShaderSocketType from_, ShaderSocketType to_)
00922 : ShaderNode("proxy")
00923 {
00924     from = from_;
00925     to = to_;
00926 
00927     add_input("Input", from);
00928     add_output("Output", to);
00929 }
00930 
00931 void ProxyNode::compile(SVMCompiler& compiler)
00932 {
00933 }
00934 
00935 void ProxyNode::compile(OSLCompiler& compiler)
00936 {
00937 }
00938 
00939 /* BSDF Closure */
00940 
00941 BsdfNode::BsdfNode()
00942 : ShaderNode("bsdf")
00943 {
00944     closure = ccl::CLOSURE_BSDF_DIFFUSE_ID;
00945 
00946     add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
00947     add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
00948 
00949     add_output("BSDF", SHADER_SOCKET_CLOSURE);
00950 }
00951 
00952 void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2)
00953 {
00954     ShaderInput *color_in = input("Color");
00955 
00956     if(color_in->link) {
00957         compiler.stack_assign(color_in);
00958         compiler.add_node(NODE_CLOSURE_WEIGHT, color_in->stack_offset);
00959     }
00960     else
00961         compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value);
00962     
00963     if(param1)
00964         compiler.stack_assign(param1);
00965     if(param2)
00966         compiler.stack_assign(param2);
00967 
00968     compiler.add_node(NODE_CLOSURE_BSDF,
00969         compiler.encode_uchar4(closure,
00970             (param1)? param1->stack_offset: SVM_STACK_INVALID,
00971             (param2)? param2->stack_offset: SVM_STACK_INVALID,
00972             compiler.closure_mix_weight_offset()),
00973         __float_as_int((param1)? param1->value.x: 0.0f),
00974         __float_as_int((param2)? param2->value.x: 0.0f));
00975 }
00976 
00977 void BsdfNode::compile(SVMCompiler& compiler)
00978 {
00979     compile(compiler, NULL, NULL);
00980 }
00981 
00982 void BsdfNode::compile(OSLCompiler& compiler)
00983 {
00984     assert(0);
00985 }
00986 
00987 /* Ward BSDF Closure */
00988 
00989 WardBsdfNode::WardBsdfNode()
00990 {
00991     closure = CLOSURE_BSDF_WARD_ID;
00992 
00993     add_input("Roughness U", SHADER_SOCKET_FLOAT, 0.2f);
00994     add_input("Roughness V", SHADER_SOCKET_FLOAT, 0.2f);
00995 }
00996 
00997 void WardBsdfNode::compile(SVMCompiler& compiler)
00998 {
00999     BsdfNode::compile(compiler, input("Roughness U"), input("Roughness V"));
01000 }
01001 
01002 void WardBsdfNode::compile(OSLCompiler& compiler)
01003 {
01004     compiler.add(this, "node_ward_bsdf");
01005 }
01006 
01007 /* Glossy BSDF Closure */
01008 
01009 static ShaderEnum glossy_distribution_init()
01010 {
01011     ShaderEnum enm;
01012 
01013     enm.insert("Sharp", CLOSURE_BSDF_REFLECTION_ID);
01014     enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
01015     enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID);
01016 
01017     return enm;
01018 }
01019 
01020 ShaderEnum GlossyBsdfNode::distribution_enum = glossy_distribution_init();
01021 
01022 GlossyBsdfNode::GlossyBsdfNode()
01023 {
01024     distribution = ustring("Beckmann");
01025 
01026     add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f);
01027 }
01028 
01029 void GlossyBsdfNode::compile(SVMCompiler& compiler)
01030 {
01031     closure = (ClosureType)distribution_enum[distribution];
01032 
01033     if(closure == CLOSURE_BSDF_REFLECTION_ID)
01034         BsdfNode::compile(compiler, NULL, NULL);
01035     else
01036         BsdfNode::compile(compiler, input("Roughness"), NULL);
01037 }
01038 
01039 void GlossyBsdfNode::compile(OSLCompiler& compiler)
01040 {
01041     compiler.parameter("distribution", distribution);
01042     compiler.add(this, "node_glossy_bsdf");
01043 }
01044 
01045 /* Glass BSDF Closure */
01046 
01047 static ShaderEnum glass_distribution_init()
01048 {
01049     ShaderEnum enm;
01050 
01051     enm.insert("Sharp", CLOSURE_BSDF_REFRACTION_ID);
01052     enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
01053     enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
01054 
01055     return enm;
01056 }
01057 
01058 ShaderEnum GlassBsdfNode::distribution_enum = glass_distribution_init();
01059 
01060 GlassBsdfNode::GlassBsdfNode()
01061 {
01062     distribution = ustring("Sharp");
01063 
01064     add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f);
01065     add_input("IOR", SHADER_SOCKET_FLOAT, 0.3f);
01066 }
01067 
01068 void GlassBsdfNode::compile(SVMCompiler& compiler)
01069 {
01070     closure = (ClosureType)distribution_enum[distribution];
01071 
01072     if(closure == CLOSURE_BSDF_REFRACTION_ID)
01073         BsdfNode::compile(compiler, NULL, input("IOR"));
01074     else
01075         BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
01076 }
01077 
01078 void GlassBsdfNode::compile(OSLCompiler& compiler)
01079 {
01080     compiler.parameter("distribution", distribution);
01081     compiler.add(this, "node_glass_bsdf");
01082 }
01083 
01084 /* Velvet BSDF Closure */
01085 
01086 VelvetBsdfNode::VelvetBsdfNode()
01087 {
01088     closure = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID;
01089 
01090     add_input("Sigma", SHADER_SOCKET_FLOAT, 1.0f);
01091 }
01092 
01093 void VelvetBsdfNode::compile(SVMCompiler& compiler)
01094 {
01095     BsdfNode::compile(compiler, input("Sigma"), NULL);
01096 }
01097 
01098 void VelvetBsdfNode::compile(OSLCompiler& compiler)
01099 {
01100     compiler.add(this, "node_velvet_bsdf");
01101 }
01102 
01103 /* Diffuse BSDF Closure */
01104 
01105 DiffuseBsdfNode::DiffuseBsdfNode()
01106 {
01107     closure = CLOSURE_BSDF_DIFFUSE_ID;
01108     add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f);
01109 }
01110 
01111 void DiffuseBsdfNode::compile(SVMCompiler& compiler)
01112 {
01113     BsdfNode::compile(compiler, input("Roughness"), NULL);
01114 }
01115 
01116 void DiffuseBsdfNode::compile(OSLCompiler& compiler)
01117 {
01118     compiler.add(this, "node_diffuse_bsdf");
01119 }
01120 
01121 /* Translucent BSDF Closure */
01122 
01123 TranslucentBsdfNode::TranslucentBsdfNode()
01124 {
01125     closure = CLOSURE_BSDF_TRANSLUCENT_ID;
01126 }
01127 
01128 void TranslucentBsdfNode::compile(SVMCompiler& compiler)
01129 {
01130     BsdfNode::compile(compiler, NULL, NULL);
01131 }
01132 
01133 void TranslucentBsdfNode::compile(OSLCompiler& compiler)
01134 {
01135     compiler.add(this, "node_translucent_bsdf");
01136 }
01137 
01138 /* Transparent BSDF Closure */
01139 
01140 TransparentBsdfNode::TransparentBsdfNode()
01141 {
01142     name = "transparent";
01143     closure = CLOSURE_BSDF_TRANSPARENT_ID;
01144 }
01145 
01146 void TransparentBsdfNode::compile(SVMCompiler& compiler)
01147 {
01148     BsdfNode::compile(compiler, NULL, NULL);
01149 }
01150 
01151 void TransparentBsdfNode::compile(OSLCompiler& compiler)
01152 {
01153     compiler.add(this, "node_transparent_bsdf");
01154 }
01155 
01156 /* Emissive Closure */
01157 
01158 EmissionNode::EmissionNode()
01159 : ShaderNode("emission")
01160 {
01161     total_power = false;
01162 
01163     add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
01164     add_input("Strength", SHADER_SOCKET_FLOAT, 10.0f);
01165     add_output("Emission", SHADER_SOCKET_CLOSURE);
01166 }
01167 
01168 void EmissionNode::compile(SVMCompiler& compiler)
01169 {
01170     ShaderInput *color_in = input("Color");
01171     ShaderInput *strength_in = input("Strength");
01172 
01173     if(color_in->link || strength_in->link) {
01174         compiler.stack_assign(color_in);
01175         compiler.stack_assign(strength_in);
01176         compiler.add_node(NODE_EMISSION_WEIGHT, color_in->stack_offset, strength_in->stack_offset, total_power? 1: 0);
01177     }
01178     else if(total_power)
01179         compiler.add_node(NODE_EMISSION_SET_WEIGHT_TOTAL, color_in->value * strength_in->value.x);
01180     else
01181         compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value * strength_in->value.x);
01182 
01183     compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset());
01184 }
01185 
01186 void EmissionNode::compile(OSLCompiler& compiler)
01187 {
01188     compiler.parameter("TotalPower", (total_power)? 1: 0);
01189     compiler.add(this, "node_emission");
01190 }
01191 
01192 /* Background Closure */
01193 
01194 BackgroundNode::BackgroundNode()
01195 : ShaderNode("background")
01196 {
01197     add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
01198     add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f);
01199     add_output("Background", SHADER_SOCKET_CLOSURE);
01200 }
01201 
01202 void BackgroundNode::compile(SVMCompiler& compiler)
01203 {
01204     ShaderInput *color_in = input("Color");
01205     ShaderInput *strength_in = input("Strength");
01206 
01207     if(color_in->link || strength_in->link) {
01208         compiler.stack_assign(color_in);
01209         compiler.stack_assign(strength_in);
01210         compiler.add_node(NODE_EMISSION_WEIGHT, color_in->stack_offset, strength_in->stack_offset);
01211     }
01212     else
01213         compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value*strength_in->value.x);
01214 
01215     compiler.add_node(NODE_CLOSURE_BACKGROUND, compiler.closure_mix_weight_offset());
01216 }
01217 
01218 void BackgroundNode::compile(OSLCompiler& compiler)
01219 {
01220     compiler.add(this, "node_background");
01221 }
01222 
01223 /* Holdout Closure */
01224 
01225 HoldoutNode::HoldoutNode()
01226 : ShaderNode("holdout")
01227 {
01228     add_output("Holdout", SHADER_SOCKET_CLOSURE);
01229 }
01230 
01231 void HoldoutNode::compile(SVMCompiler& compiler)
01232 {
01233     compiler.add_node(NODE_CLOSURE_HOLDOUT, compiler.closure_mix_weight_offset());
01234 }
01235 
01236 void HoldoutNode::compile(OSLCompiler& compiler)
01237 {
01238     compiler.add(this, "node_holdout");
01239 }
01240 
01241 /* Volume Closure */
01242 
01243 VolumeNode::VolumeNode()
01244 : ShaderNode("volume")
01245 {
01246     closure = ccl::CLOSURE_VOLUME_ISOTROPIC_ID;
01247 
01248     add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
01249     add_input("Density", SHADER_SOCKET_FLOAT, 1.0f);
01250 
01251     add_output("Volume", SHADER_SOCKET_CLOSURE);
01252 }
01253 
01254 void VolumeNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2)
01255 {
01256     ShaderInput *color_in = input("Color");
01257 
01258     if(color_in->link) {
01259         compiler.stack_assign(color_in);
01260         compiler.add_node(NODE_CLOSURE_WEIGHT, color_in->stack_offset);
01261     }
01262     else
01263         compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value);
01264     
01265     if(param1)
01266         compiler.stack_assign(param1);
01267     if(param2)
01268         compiler.stack_assign(param2);
01269 
01270     compiler.add_node(NODE_CLOSURE_VOLUME,
01271         compiler.encode_uchar4(closure,
01272             (param1)? param1->stack_offset: SVM_STACK_INVALID,
01273             (param2)? param2->stack_offset: SVM_STACK_INVALID,
01274             compiler.closure_mix_weight_offset()),
01275         __float_as_int((param1)? param1->value.x: 0.0f),
01276         __float_as_int((param2)? param2->value.x: 0.0f));
01277 }
01278 
01279 void VolumeNode::compile(SVMCompiler& compiler)
01280 {
01281     compile(compiler, NULL, NULL);
01282 }
01283 
01284 void VolumeNode::compile(OSLCompiler& compiler)
01285 {
01286     assert(0);
01287 }
01288 
01289 /* Transparent Volume Closure */
01290 
01291 TransparentVolumeNode::TransparentVolumeNode()
01292 {
01293     closure = CLOSURE_VOLUME_TRANSPARENT_ID;
01294 }
01295 
01296 void TransparentVolumeNode::compile(SVMCompiler& compiler)
01297 {
01298     VolumeNode::compile(compiler, input("Density"), NULL);
01299 }
01300 
01301 void TransparentVolumeNode::compile(OSLCompiler& compiler)
01302 {
01303     compiler.add(this, "node_isotropic_volume");
01304 }
01305 
01306 /* Isotropic Volume Closure */
01307 
01308 IsotropicVolumeNode::IsotropicVolumeNode()
01309 {
01310     closure = CLOSURE_VOLUME_ISOTROPIC_ID;
01311 }
01312 
01313 void IsotropicVolumeNode::compile(SVMCompiler& compiler)
01314 {
01315     VolumeNode::compile(compiler, input("Density"), NULL);
01316 }
01317 
01318 void IsotropicVolumeNode::compile(OSLCompiler& compiler)
01319 {
01320     compiler.add(this, "node_isotropic_volume");
01321 }
01322 
01323 /* Geometry */
01324 
01325 GeometryNode::GeometryNode()
01326 : ShaderNode("geometry")
01327 {
01328     add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
01329     add_output("Position", SHADER_SOCKET_POINT);
01330     add_output("Normal", SHADER_SOCKET_NORMAL);
01331     add_output("Tangent", SHADER_SOCKET_NORMAL);
01332     add_output("True Normal", SHADER_SOCKET_NORMAL);
01333     add_output("Incoming", SHADER_SOCKET_VECTOR);
01334     add_output("Parametric", SHADER_SOCKET_POINT);
01335     add_output("Backfacing", SHADER_SOCKET_FLOAT);
01336 }
01337 
01338 void GeometryNode::compile(SVMCompiler& compiler)
01339 {
01340     ShaderOutput *out;
01341     NodeType geom_node = NODE_GEOMETRY;
01342 
01343     if(bump == SHADER_BUMP_DX)
01344         geom_node = NODE_GEOMETRY_BUMP_DX;
01345     else if(bump == SHADER_BUMP_DY)
01346         geom_node = NODE_GEOMETRY_BUMP_DY;
01347     
01348     out = output("Position");
01349     if(!out->links.empty()) {
01350         compiler.stack_assign(out);
01351         compiler.add_node(geom_node, NODE_GEOM_P, out->stack_offset);
01352     }
01353 
01354     out = output("Normal");
01355     if(!out->links.empty()) {
01356         compiler.stack_assign(out);
01357         compiler.add_node(geom_node, NODE_GEOM_N, out->stack_offset);
01358     }
01359 
01360     out = output("Tangent");
01361     if(!out->links.empty()) {
01362         compiler.stack_assign(out);
01363         compiler.add_node(geom_node, NODE_GEOM_T, out->stack_offset);
01364     }
01365 
01366     out = output("True Normal");
01367     if(!out->links.empty()) {
01368         compiler.stack_assign(out);
01369         compiler.add_node(geom_node, NODE_GEOM_Ng, out->stack_offset);
01370     }
01371 
01372     out = output("Incoming");
01373     if(!out->links.empty()) {
01374         compiler.stack_assign(out);
01375         compiler.add_node(geom_node, NODE_GEOM_I, out->stack_offset);
01376     }
01377 
01378     out = output("Parametric");
01379     if(!out->links.empty()) {
01380         compiler.stack_assign(out);
01381         compiler.add_node(geom_node, NODE_GEOM_uv, out->stack_offset);
01382     }
01383 
01384     out = output("Backfacing");
01385     if(!out->links.empty()) {
01386         compiler.stack_assign(out);
01387         compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, out->stack_offset);
01388     }
01389 }
01390 
01391 void GeometryNode::compile(OSLCompiler& compiler)
01392 {
01393     if(bump == SHADER_BUMP_DX)
01394         compiler.parameter("bump_offset", "dx");
01395     else if(bump == SHADER_BUMP_DY)
01396         compiler.parameter("bump_offset", "dy");
01397     else
01398         compiler.parameter("bump_offset", "center");
01399 
01400     compiler.add(this, "node_geometry");
01401 }
01402 
01403 /* TextureCoordinate */
01404 
01405 TextureCoordinateNode::TextureCoordinateNode()
01406 : ShaderNode("texture_coordinate")
01407 {
01408     add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
01409     add_output("Generated", SHADER_SOCKET_POINT);
01410     add_output("UV", SHADER_SOCKET_POINT);
01411     add_output("Object", SHADER_SOCKET_POINT);
01412     add_output("Camera", SHADER_SOCKET_POINT);
01413     add_output("Window", SHADER_SOCKET_POINT);
01414     add_output("Reflection", SHADER_SOCKET_NORMAL);
01415 }
01416 
01417 void TextureCoordinateNode::attributes(AttributeRequestSet *attributes)
01418 {
01419     if(!output("Generated")->links.empty())
01420         attributes->add(Attribute::STD_GENERATED);
01421     if(!output("UV")->links.empty())
01422         attributes->add(Attribute::STD_UV);
01423 
01424     ShaderNode::attributes(attributes);
01425 }
01426 
01427 void TextureCoordinateNode::compile(SVMCompiler& compiler)
01428 {
01429     ShaderOutput *out;
01430     NodeType texco_node = NODE_TEX_COORD;
01431     NodeType attr_node = NODE_ATTR;
01432     NodeType geom_node = NODE_GEOMETRY;
01433 
01434     if(bump == SHADER_BUMP_DX) {
01435         texco_node = NODE_TEX_COORD_BUMP_DX;
01436         attr_node = NODE_ATTR_BUMP_DX;
01437         geom_node = NODE_GEOMETRY_BUMP_DX;
01438     }
01439     else if(bump == SHADER_BUMP_DY) {
01440         texco_node = NODE_TEX_COORD_BUMP_DY;
01441         attr_node = NODE_ATTR_BUMP_DY;
01442         geom_node = NODE_GEOMETRY_BUMP_DY;
01443     }
01444     
01445     out = output("Generated");
01446     if(!out->links.empty()) {
01447         if(compiler.background) {
01448             compiler.stack_assign(out);
01449             compiler.add_node(geom_node, NODE_GEOM_P, out->stack_offset);
01450         }
01451         else {
01452             int attr = compiler.attribute(Attribute::STD_GENERATED);
01453             compiler.stack_assign(out);
01454             compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3);
01455         }
01456     }
01457 
01458     out = output("UV");
01459     if(!out->links.empty()) {
01460         int attr = compiler.attribute(Attribute::STD_UV);
01461         compiler.stack_assign(out);
01462         compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3);
01463     }
01464 
01465     out = output("Object");
01466     if(!out->links.empty()) {
01467         compiler.stack_assign(out);
01468         compiler.add_node(texco_node, NODE_TEXCO_OBJECT, out->stack_offset);
01469     }
01470 
01471     out = output("Camera");
01472     if(!out->links.empty()) {
01473         compiler.stack_assign(out);
01474         compiler.add_node(texco_node, NODE_TEXCO_CAMERA, out->stack_offset);
01475     }
01476 
01477     out = output("Window");
01478     if(!out->links.empty()) {
01479         compiler.stack_assign(out);
01480         compiler.add_node(texco_node, NODE_TEXCO_WINDOW, out->stack_offset);
01481     }
01482 
01483     out = output("Reflection");
01484     if(!out->links.empty()) {
01485         if(compiler.background) {
01486             compiler.stack_assign(out);
01487             compiler.add_node(geom_node, NODE_GEOM_I, out->stack_offset);
01488         }
01489         else {
01490             compiler.stack_assign(out);
01491             compiler.add_node(texco_node, NODE_TEXCO_REFLECTION, out->stack_offset);
01492         }
01493     }
01494 }
01495 
01496 void TextureCoordinateNode::compile(OSLCompiler& compiler)
01497 {
01498     if(bump == SHADER_BUMP_DX)
01499         compiler.parameter("bump_offset", "dx");
01500     else if(bump == SHADER_BUMP_DY)
01501         compiler.parameter("bump_offset", "dy");
01502     else
01503         compiler.parameter("bump_offset", "center");
01504     
01505     if(compiler.background)
01506         compiler.parameter("is_background", true);
01507 
01508     compiler.add(this, "node_texture_coordinate");
01509 }
01510 
01511 /* Light Path */
01512 
01513 LightPathNode::LightPathNode()
01514 : ShaderNode("light_path")
01515 {
01516     add_output("Is Camera Ray", SHADER_SOCKET_FLOAT);
01517     add_output("Is Shadow Ray", SHADER_SOCKET_FLOAT);
01518     add_output("Is Diffuse Ray", SHADER_SOCKET_FLOAT);
01519     add_output("Is Glossy Ray", SHADER_SOCKET_FLOAT);
01520     add_output("Is Singular Ray", SHADER_SOCKET_FLOAT);
01521     add_output("Is Reflection Ray", SHADER_SOCKET_FLOAT);
01522     add_output("Is Transmission Ray", SHADER_SOCKET_FLOAT);
01523 }
01524 
01525 void LightPathNode::compile(SVMCompiler& compiler)
01526 {
01527     ShaderOutput *out;
01528 
01529     out = output("Is Camera Ray");
01530     if(!out->links.empty()) {
01531         compiler.stack_assign(out);
01532         compiler.add_node(NODE_LIGHT_PATH, NODE_LP_camera, out->stack_offset);
01533     }
01534 
01535     out = output("Is Shadow Ray");
01536     if(!out->links.empty()) {
01537         compiler.stack_assign(out);
01538         compiler.add_node(NODE_LIGHT_PATH, NODE_LP_shadow, out->stack_offset);
01539     }
01540 
01541     out = output("Is Diffuse Ray");
01542     if(!out->links.empty()) {
01543         compiler.stack_assign(out);
01544         compiler.add_node(NODE_LIGHT_PATH, NODE_LP_diffuse, out->stack_offset);
01545     }
01546 
01547     out = output("Is Glossy Ray");
01548     if(!out->links.empty()) {
01549         compiler.stack_assign(out);
01550         compiler.add_node(NODE_LIGHT_PATH, NODE_LP_glossy, out->stack_offset);
01551     }
01552 
01553     out = output("Is Singular Ray");
01554     if(!out->links.empty()) {
01555         compiler.stack_assign(out);
01556         compiler.add_node(NODE_LIGHT_PATH, NODE_LP_singular, out->stack_offset);
01557     }
01558 
01559     out = output("Is Reflection Ray");
01560     if(!out->links.empty()) {
01561         compiler.stack_assign(out);
01562         compiler.add_node(NODE_LIGHT_PATH, NODE_LP_reflection, out->stack_offset);
01563     }
01564 
01565 
01566     out = output("Is Transmission Ray");
01567     if(!out->links.empty()) {
01568         compiler.stack_assign(out);
01569         compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, out->stack_offset);
01570     }
01571 }
01572 
01573 void LightPathNode::compile(OSLCompiler& compiler)
01574 {
01575     compiler.add(this, "node_light_path");
01576 }
01577 
01578 /* Value */
01579 
01580 ValueNode::ValueNode()
01581 : ShaderNode("value")
01582 {
01583     value = 0.0f;
01584 
01585     add_output("Value", SHADER_SOCKET_FLOAT);
01586 }
01587 
01588 void ValueNode::compile(SVMCompiler& compiler)
01589 {
01590     ShaderOutput *val_out = output("Value");
01591 
01592     compiler.stack_assign(val_out);
01593     compiler.add_node(NODE_VALUE_F, __float_as_int(value), val_out->stack_offset);
01594 }
01595 
01596 void ValueNode::compile(OSLCompiler& compiler)
01597 {
01598     compiler.parameter("value_value", value);
01599     compiler.add(this, "node_value");
01600 }
01601 
01602 /* Color */
01603 
01604 ColorNode::ColorNode()
01605 : ShaderNode("color")
01606 {
01607     value = make_float3(0.0f, 0.0f, 0.0f);
01608 
01609     add_output("Color", SHADER_SOCKET_COLOR);
01610 }
01611 
01612 void ColorNode::compile(SVMCompiler& compiler)
01613 {
01614     ShaderOutput *color_out = output("Color");
01615 
01616     if(color_out && !color_out->links.empty()) {
01617         compiler.stack_assign(color_out);
01618         compiler.add_node(NODE_VALUE_V, color_out->stack_offset);
01619         compiler.add_node(NODE_VALUE_V, value);
01620     }
01621 }
01622 
01623 void ColorNode::compile(OSLCompiler& compiler)
01624 {
01625     compiler.parameter_color("color_value", value);
01626 
01627     compiler.add(this, "node_value");
01628 }
01629 
01630 /* Add Closure */
01631 
01632 AddClosureNode::AddClosureNode()
01633 : ShaderNode("add_closure")
01634 {
01635     add_input("Closure1", SHADER_SOCKET_CLOSURE);
01636     add_input("Closure2", SHADER_SOCKET_CLOSURE);
01637     add_output("Closure",  SHADER_SOCKET_CLOSURE);
01638 }
01639 
01640 void AddClosureNode::compile(SVMCompiler& compiler)
01641 {
01642     /* handled in the SVM compiler */
01643 }
01644 
01645 void AddClosureNode::compile(OSLCompiler& compiler)
01646 {
01647     compiler.add(this, "node_add_closure");
01648 }
01649 
01650 /* Mix Closure */
01651 
01652 MixClosureNode::MixClosureNode()
01653 : ShaderNode("mix_closure")
01654 {
01655     add_input("Fac", SHADER_SOCKET_FLOAT, 0.5f);
01656     add_input("Closure1", SHADER_SOCKET_CLOSURE);
01657     add_input("Closure2", SHADER_SOCKET_CLOSURE);
01658     add_output("Closure",  SHADER_SOCKET_CLOSURE);
01659 }
01660 
01661 void MixClosureNode::compile(SVMCompiler& compiler)
01662 {
01663     /* handled in the SVM compiler */
01664 }
01665 
01666 void MixClosureNode::compile(OSLCompiler& compiler)
01667 {
01668     compiler.add(this, "node_mix_closure");
01669 }
01670 
01671 /* Invert */
01672 
01673 InvertNode::InvertNode()
01674 : ShaderNode("invert")
01675 {
01676     add_input("Fac", SHADER_SOCKET_FLOAT, 1.0f);
01677     add_input("Color", SHADER_SOCKET_COLOR);
01678     add_output("Color",  SHADER_SOCKET_COLOR);
01679 }
01680 
01681 void InvertNode::compile(SVMCompiler& compiler)
01682 {
01683     ShaderInput *fac_in = input("Fac");
01684     ShaderInput *color_in = input("Color");
01685     ShaderOutput *color_out = output("Color");
01686 
01687     compiler.stack_assign(fac_in);
01688     compiler.stack_assign(color_in);
01689     compiler.stack_assign(color_out);
01690 
01691     compiler.add_node(NODE_INVERT, fac_in->stack_offset, color_in->stack_offset, color_out->stack_offset);
01692 }
01693 
01694 void InvertNode::compile(OSLCompiler& compiler)
01695 {
01696     compiler.add(this, "node_invert");
01697 }
01698 
01699 /* Mix */
01700 
01701 MixNode::MixNode()
01702 : ShaderNode("mix")
01703 {
01704     type = ustring("Mix");
01705 
01706     add_input("Fac", SHADER_SOCKET_FLOAT, 0.5f);
01707     add_input("Color1", SHADER_SOCKET_COLOR);
01708     add_input("Color2", SHADER_SOCKET_COLOR);
01709     add_output("Color",  SHADER_SOCKET_COLOR);
01710 }
01711 
01712 static ShaderEnum mix_type_init()
01713 {
01714     ShaderEnum enm;
01715 
01716     enm.insert("Mix", NODE_MIX_BLEND);
01717     enm.insert("Add", NODE_MIX_ADD);
01718     enm.insert("Multiply", NODE_MIX_MUL);
01719     enm.insert("Screen", NODE_MIX_SCREEN);
01720     enm.insert("Overlay", NODE_MIX_OVERLAY);
01721     enm.insert("Subtract", NODE_MIX_SUB);
01722     enm.insert("Divide", NODE_MIX_DIV);
01723     enm.insert("Difference", NODE_MIX_DIFF);
01724     enm.insert("Darken", NODE_MIX_DARK);
01725     enm.insert("Lighten", NODE_MIX_LIGHT);
01726     enm.insert("Dodge", NODE_MIX_DODGE);
01727     enm.insert("Burn", NODE_MIX_BURN);
01728     enm.insert("Hue", NODE_MIX_HUE);
01729     enm.insert("Saturation", NODE_MIX_SAT);
01730     enm.insert("Value", NODE_MIX_VAL );
01731     enm.insert("Color", NODE_MIX_COLOR);
01732     enm.insert("Soft Light", NODE_MIX_SOFT);
01733     enm.insert("Linear Light", NODE_MIX_LINEAR);
01734 
01735     return enm;
01736 }
01737 
01738 ShaderEnum MixNode::type_enum = mix_type_init();
01739 
01740 void MixNode::compile(SVMCompiler& compiler)
01741 {
01742     ShaderInput *fac_in = input("Fac");
01743     ShaderInput *color1_in = input("Color1");
01744     ShaderInput *color2_in = input("Color2");
01745     ShaderOutput *color_out = output("Color");
01746 
01747     compiler.stack_assign(fac_in);
01748     compiler.stack_assign(color1_in);
01749     compiler.stack_assign(color2_in);
01750     compiler.stack_assign(color_out);
01751 
01752     compiler.add_node(NODE_MIX, fac_in->stack_offset, color1_in->stack_offset, color2_in->stack_offset);
01753     compiler.add_node(NODE_MIX, type_enum[type], color_out->stack_offset);
01754 }
01755 
01756 void MixNode::compile(OSLCompiler& compiler)
01757 {
01758     compiler.parameter("type", type);
01759     compiler.add(this, "node_mix");
01760 }
01761 
01762 /* Combine RGB */
01763 CombineRGBNode::CombineRGBNode()
01764 : ShaderNode("combine_rgb")
01765 {
01766     add_input("R", SHADER_SOCKET_FLOAT);
01767     add_input("G", SHADER_SOCKET_FLOAT);
01768     add_input("B", SHADER_SOCKET_FLOAT);
01769     add_output("Image", SHADER_SOCKET_COLOR);
01770 }
01771 
01772 void CombineRGBNode::compile(SVMCompiler& compiler)
01773 {
01774     ShaderInput *red_in = input("R");
01775     ShaderInput *green_in = input("G");
01776     ShaderInput *blue_in = input("B");
01777     ShaderOutput *color_out = output("Image");
01778 
01779     compiler.stack_assign(color_out);
01780 
01781     compiler.stack_assign(red_in);
01782     compiler.add_node(NODE_COMBINE_RGB, red_in->stack_offset, 0, color_out->stack_offset);
01783 
01784     compiler.stack_assign(green_in);
01785     compiler.add_node(NODE_COMBINE_RGB, green_in->stack_offset, 1, color_out->stack_offset);
01786 
01787     compiler.stack_assign(blue_in);
01788     compiler.add_node(NODE_COMBINE_RGB, blue_in->stack_offset, 2, color_out->stack_offset);
01789 }
01790 
01791 void CombineRGBNode::compile(OSLCompiler& compiler)
01792 {
01793     compiler.add(this, "node_combine_rgb");
01794 }
01795 
01796 /* Gamma */
01797 GammaNode::GammaNode()
01798 : ShaderNode("gamma")
01799 {
01800     add_input("Color", SHADER_SOCKET_COLOR);
01801     add_input("Gamma", SHADER_SOCKET_FLOAT);
01802     add_output("Color", SHADER_SOCKET_COLOR);
01803 }
01804 
01805 void GammaNode::compile(SVMCompiler& compiler)
01806 {
01807     ShaderInput *color_in = input("Color");
01808     ShaderInput *gamma_in = input("Gamma");
01809     ShaderOutput *color_out = output("Color");
01810 
01811     compiler.stack_assign(color_in);
01812     compiler.stack_assign(gamma_in);
01813     compiler.stack_assign(color_out);
01814 
01815     compiler.add_node(NODE_GAMMA, gamma_in->stack_offset, color_in->stack_offset, color_out->stack_offset);
01816 }
01817 
01818 void GammaNode::compile(OSLCompiler& compiler)
01819 {
01820     compiler.add(this, "node_gamma");
01821 }
01822 
01823 /* Separate RGB */
01824 SeparateRGBNode::SeparateRGBNode()
01825 : ShaderNode("separate_rgb")
01826 {
01827     add_input("Image", SHADER_SOCKET_COLOR);
01828     add_output("R", SHADER_SOCKET_FLOAT);
01829     add_output("G", SHADER_SOCKET_FLOAT);
01830     add_output("B", SHADER_SOCKET_FLOAT);
01831 }
01832 
01833 void SeparateRGBNode::compile(SVMCompiler& compiler)
01834 {
01835     ShaderInput *color_in = input("Image");
01836     ShaderOutput *red_out = output("R");
01837     ShaderOutput *green_out = output("G");
01838     ShaderOutput *blue_out = output("B");
01839 
01840     compiler.stack_assign(color_in);
01841 
01842     compiler.stack_assign(red_out);
01843     compiler.add_node(NODE_SEPARATE_RGB, color_in->stack_offset, 0, red_out->stack_offset);
01844 
01845     compiler.stack_assign(green_out);
01846     compiler.add_node(NODE_SEPARATE_RGB, color_in->stack_offset, 1, green_out->stack_offset);
01847 
01848     compiler.stack_assign(blue_out);
01849     compiler.add_node(NODE_SEPARATE_RGB, color_in->stack_offset, 2, blue_out->stack_offset);
01850 }
01851 
01852 void SeparateRGBNode::compile(OSLCompiler& compiler)
01853 {
01854     compiler.add(this, "node_separate_rgb");
01855 }
01856 
01857 /* Separate RGB */
01858 HSVNode::HSVNode()
01859 : ShaderNode("hsv")
01860 {
01861     add_input("Hue", SHADER_SOCKET_FLOAT);
01862     add_input("Saturation", SHADER_SOCKET_FLOAT);
01863     add_input("Value", SHADER_SOCKET_FLOAT);
01864     add_input("Fac", SHADER_SOCKET_FLOAT);
01865     add_input("Color", SHADER_SOCKET_COLOR);
01866     add_output("Color", SHADER_SOCKET_COLOR);
01867 }
01868 
01869 void HSVNode::compile(SVMCompiler& compiler)
01870 {
01871     ShaderInput *hue_in = input("Hue");
01872     ShaderInput *saturation_in = input("Saturation");
01873     ShaderInput *value_in = input("Value");
01874     ShaderInput *fac_in = input("Fac");
01875     ShaderInput *color_in = input("Color");
01876     ShaderOutput *color_out = output("Color");
01877 
01878     compiler.stack_assign(hue_in);
01879     compiler.stack_assign(saturation_in);
01880     compiler.stack_assign(value_in);
01881     compiler.stack_assign(fac_in);
01882     compiler.stack_assign(color_in);
01883     compiler.stack_assign(color_out);
01884 
01885     compiler.add_node(NODE_HSV, color_in->stack_offset, fac_in->stack_offset, color_out->stack_offset);
01886     compiler.add_node(NODE_HSV, hue_in->stack_offset, saturation_in->stack_offset, value_in->stack_offset);
01887 }
01888 
01889 void HSVNode::compile(OSLCompiler& compiler)
01890 {
01891     compiler.add(this, "node_hsv");
01892 }
01893 
01894 /* Attribute */
01895 
01896 AttributeNode::AttributeNode()
01897 : ShaderNode("attribute")
01898 {
01899     attribute = "";
01900 
01901     add_output("Color",  SHADER_SOCKET_COLOR);
01902     add_output("Vector",  SHADER_SOCKET_VECTOR);
01903     add_output("Fac",  SHADER_SOCKET_FLOAT);
01904 }
01905 
01906 void AttributeNode::attributes(AttributeRequestSet *attributes)
01907 {
01908     ShaderOutput *color_out = output("Color");
01909     ShaderOutput *vector_out = output("Vector");
01910     ShaderOutput *fac_out = output("Fac");
01911 
01912     if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty())
01913         attributes->add(attribute);
01914     
01915     ShaderNode::attributes(attributes);
01916 }
01917 
01918 void AttributeNode::compile(SVMCompiler& compiler)
01919 {
01920     ShaderOutput *color_out = output("Color");
01921     ShaderOutput *vector_out = output("Vector");
01922     ShaderOutput *fac_out = output("Fac");
01923     NodeType attr_node = NODE_ATTR;
01924 
01925     if(bump == SHADER_BUMP_DX)
01926         attr_node = NODE_ATTR_BUMP_DX;
01927     else if(bump == SHADER_BUMP_DY)
01928         attr_node = NODE_ATTR_BUMP_DY;
01929 
01930     if(!color_out->links.empty() || !vector_out->links.empty()) {
01931         int attr = compiler.attribute(attribute);
01932 
01933         if(!color_out->links.empty()) {
01934             compiler.stack_assign(color_out);
01935             compiler.add_node(attr_node, attr, color_out->stack_offset, NODE_ATTR_FLOAT3);
01936         }
01937         if(!vector_out->links.empty()) {
01938             compiler.stack_assign(vector_out);
01939             compiler.add_node(attr_node, attr, vector_out->stack_offset, NODE_ATTR_FLOAT3);
01940         }
01941     }
01942 
01943     if(!fac_out->links.empty()) {
01944         int attr = compiler.attribute(attribute);
01945 
01946         compiler.stack_assign(fac_out);
01947         compiler.add_node(attr_node, attr, fac_out->stack_offset, NODE_ATTR_FLOAT);
01948     }
01949 }
01950 
01951 void AttributeNode::compile(OSLCompiler& compiler)
01952 {
01953     if(bump == SHADER_BUMP_DX)
01954         compiler.parameter("bump_offset", "dx");
01955     else if(bump == SHADER_BUMP_DY)
01956         compiler.parameter("bump_offset", "dy");
01957     else
01958         compiler.parameter("bump_offset", "center");
01959 
01960     compiler.parameter("name", attribute.c_str());
01961     compiler.add(this, "node_attribute");
01962 }
01963 
01964 /* Camera */
01965 
01966 CameraNode::CameraNode()
01967 : ShaderNode("camera")
01968 {
01969     add_output("View Vector",  SHADER_SOCKET_VECTOR);
01970     add_output("View Z Depth",  SHADER_SOCKET_FLOAT);
01971     add_output("View Distance",  SHADER_SOCKET_FLOAT);
01972 }
01973 
01974 void CameraNode::compile(SVMCompiler& compiler)
01975 {
01976     ShaderOutput *vector_out = output("View Vector");
01977     ShaderOutput *z_depth_out = output("View Z Depth");
01978     ShaderOutput *distance_out = output("View Distance");
01979 
01980     compiler.stack_assign(vector_out);
01981     compiler.stack_assign(z_depth_out);
01982     compiler.stack_assign(distance_out);
01983     compiler.add_node(NODE_CAMERA, vector_out->stack_offset, z_depth_out->stack_offset, distance_out->stack_offset);
01984 }
01985 
01986 void CameraNode::compile(OSLCompiler& compiler)
01987 {
01988     compiler.add(this, "node_camera");
01989 }
01990 
01991 /* Fresnel */
01992 
01993 FresnelNode::FresnelNode()
01994 : ShaderNode("Fresnel")
01995 {
01996     add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
01997     add_input("IOR", SHADER_SOCKET_FLOAT, 1.45f);
01998     add_output("Fac", SHADER_SOCKET_FLOAT);
01999 }
02000 
02001 void FresnelNode::compile(SVMCompiler& compiler)
02002 {
02003     ShaderInput *ior_in = input("IOR");
02004     ShaderOutput *fac_out = output("Fac");
02005 
02006     compiler.stack_assign(ior_in);
02007     compiler.stack_assign(fac_out);
02008     compiler.add_node(NODE_FRESNEL, ior_in->stack_offset, __float_as_int(ior_in->value.x), fac_out->stack_offset);
02009 }
02010 
02011 void FresnelNode::compile(OSLCompiler& compiler)
02012 {
02013     compiler.add(this, "node_fresnel");
02014 }
02015 
02016 /* Blend Weight */
02017 
02018 LayerWeightNode::LayerWeightNode()
02019 : ShaderNode("LayerWeight")
02020 {
02021     add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
02022     add_input("Blend", SHADER_SOCKET_FLOAT, 0.5f);
02023 
02024     add_output("Fresnel", SHADER_SOCKET_FLOAT);
02025     add_output("Facing", SHADER_SOCKET_FLOAT);
02026 }
02027 
02028 void LayerWeightNode::compile(SVMCompiler& compiler)
02029 {
02030     ShaderInput *blend_in = input("Blend");
02031 
02032     if(blend_in->link)
02033         compiler.stack_assign(blend_in);
02034 
02035     ShaderOutput *fresnel_out = output("Fresnel");
02036     if(!fresnel_out->links.empty()) {
02037         compiler.stack_assign(fresnel_out);
02038         compiler.add_node(NODE_LAYER_WEIGHT, blend_in->stack_offset, __float_as_int(blend_in->value.x),
02039             compiler.encode_uchar4(NODE_LAYER_WEIGHT_FRESNEL, fresnel_out->stack_offset));
02040     }
02041 
02042     ShaderOutput *facing_out = output("Facing");
02043     if(!facing_out->links.empty()) {
02044         compiler.stack_assign(facing_out);
02045         compiler.add_node(NODE_LAYER_WEIGHT, blend_in->stack_offset, __float_as_int(blend_in->value.x),
02046             compiler.encode_uchar4(NODE_LAYER_WEIGHT_FACING, facing_out->stack_offset));
02047     }
02048 }
02049 
02050 void LayerWeightNode::compile(OSLCompiler& compiler)
02051 {
02052     compiler.add(this, "node_layer_height");
02053 }
02054 
02055 /* Output */
02056 
02057 OutputNode::OutputNode()
02058 : ShaderNode("output")
02059 {
02060     add_input("Surface", SHADER_SOCKET_CLOSURE);
02061     add_input("Volume", SHADER_SOCKET_CLOSURE);
02062     add_input("Displacement", SHADER_SOCKET_FLOAT);
02063 }
02064 
02065 void OutputNode::compile(SVMCompiler& compiler)
02066 {
02067     if(compiler.output_type() == SHADER_TYPE_DISPLACEMENT) {
02068         ShaderInput *displacement_in = input("Displacement");
02069 
02070         if(displacement_in->link) {
02071             compiler.stack_assign(displacement_in);
02072             compiler.add_node(NODE_SET_DISPLACEMENT, displacement_in->stack_offset);
02073         }
02074     }
02075 }
02076 
02077 void OutputNode::compile(OSLCompiler& compiler)
02078 {
02079     if(compiler.output_type() == SHADER_TYPE_SURFACE)
02080         compiler.add(this, "node_output_surface");
02081     else if(compiler.output_type() == SHADER_TYPE_VOLUME)
02082         compiler.add(this, "node_output_volume");
02083     else if(compiler.output_type() == SHADER_TYPE_DISPLACEMENT)
02084         compiler.add(this, "node_output_displacement");
02085 }
02086 
02087 /* Math */
02088 
02089 MathNode::MathNode()
02090 : ShaderNode("math")
02091 {
02092     type = ustring("Add");
02093 
02094     add_input("Value1", SHADER_SOCKET_FLOAT);
02095     add_input("Value2", SHADER_SOCKET_FLOAT);
02096     add_output("Value",  SHADER_SOCKET_FLOAT);
02097 }
02098 
02099 static ShaderEnum math_type_init()
02100 {
02101     ShaderEnum enm;
02102 
02103     enm.insert("Add", NODE_MATH_ADD);
02104     enm.insert("Subtract", NODE_MATH_SUBTRACT);
02105     enm.insert("Multiply", NODE_MATH_MULTIPLY);
02106     enm.insert("Divide", NODE_MATH_DIVIDE);
02107     enm.insert("Sine", NODE_MATH_SINE);
02108     enm.insert("Cosine", NODE_MATH_COSINE);
02109     enm.insert("Tangent", NODE_MATH_TANGENT);
02110     enm.insert("Arcsine", NODE_MATH_ARCSINE);
02111     enm.insert("Arccosine", NODE_MATH_ARCCOSINE);
02112     enm.insert("Arctangent", NODE_MATH_ARCTANGENT);
02113     enm.insert("Power", NODE_MATH_POWER);
02114     enm.insert("Logarithm", NODE_MATH_LOGARITHM);
02115     enm.insert("Minimum", NODE_MATH_MINIMUM);
02116     enm.insert("Maximum", NODE_MATH_MAXIMUM);
02117     enm.insert("Round", NODE_MATH_ROUND);
02118     enm.insert("Less Than", NODE_MATH_LESS_THAN);
02119     enm.insert("Greater Than", NODE_MATH_GREATER_THAN);
02120 
02121     return enm;
02122 }
02123 
02124 ShaderEnum MathNode::type_enum = math_type_init();
02125 
02126 void MathNode::compile(SVMCompiler& compiler)
02127 {
02128     ShaderInput *value1_in = input("Value1");
02129     ShaderInput *value2_in = input("Value2");
02130     ShaderOutput *value_out = output("Value");
02131 
02132     compiler.stack_assign(value1_in);
02133     compiler.stack_assign(value2_in);
02134     compiler.stack_assign(value_out);
02135 
02136     compiler.add_node(NODE_MATH, type_enum[type], value1_in->stack_offset, value2_in->stack_offset);
02137     compiler.add_node(NODE_MATH, value_out->stack_offset);
02138 }
02139 
02140 void MathNode::compile(OSLCompiler& compiler)
02141 {
02142     compiler.parameter("type", type);
02143     compiler.add(this, "node_math");
02144 }
02145 
02146 /* VectorMath */
02147 
02148 VectorMathNode::VectorMathNode()
02149 : ShaderNode("vector_math")
02150 {
02151     type = ustring("Add");
02152 
02153     add_input("Vector1", SHADER_SOCKET_VECTOR);
02154     add_input("Vector2", SHADER_SOCKET_VECTOR);
02155     add_output("Value",  SHADER_SOCKET_FLOAT);
02156     add_output("Vector",  SHADER_SOCKET_VECTOR);
02157 }
02158 
02159 static ShaderEnum vector_math_type_init()
02160 {
02161     ShaderEnum enm;
02162 
02163     enm.insert("Add", NODE_VECTOR_MATH_ADD);
02164     enm.insert("Subtract", NODE_VECTOR_MATH_SUBTRACT);
02165     enm.insert("Average", NODE_VECTOR_MATH_AVERAGE);
02166     enm.insert("Dot Product", NODE_VECTOR_MATH_DOT_PRODUCT);
02167     enm.insert("Cross Product", NODE_VECTOR_MATH_CROSS_PRODUCT);
02168     enm.insert("Normalize", NODE_VECTOR_MATH_NORMALIZE);
02169 
02170     return enm;
02171 }
02172 
02173 ShaderEnum VectorMathNode::type_enum = vector_math_type_init();
02174 
02175 void VectorMathNode::compile(SVMCompiler& compiler)
02176 {
02177     ShaderInput *vector1_in = input("Vector1");
02178     ShaderInput *vector2_in = input("Vector2");
02179     ShaderOutput *value_out = output("Value");
02180     ShaderOutput *vector_out = output("Vector");
02181 
02182     compiler.stack_assign(vector1_in);
02183     compiler.stack_assign(vector2_in);
02184     compiler.stack_assign(value_out);
02185     compiler.stack_assign(vector_out);
02186 
02187     compiler.add_node(NODE_VECTOR_MATH, type_enum[type], vector1_in->stack_offset, vector2_in->stack_offset);
02188     compiler.add_node(NODE_VECTOR_MATH, value_out->stack_offset, vector_out->stack_offset);
02189 }
02190 
02191 void VectorMathNode::compile(OSLCompiler& compiler)
02192 {
02193     compiler.parameter("type", type);
02194     compiler.add(this, "node_vector_math");
02195 }
02196 
02197 /* BumpNode */
02198 
02199 BumpNode::BumpNode()
02200 : ShaderNode("bump")
02201 {
02202     add_input("SampleCenter", SHADER_SOCKET_FLOAT);
02203     add_input("SampleX", SHADER_SOCKET_FLOAT);
02204     add_input("SampleY", SHADER_SOCKET_FLOAT);
02205 
02206     add_output("Normal", SHADER_SOCKET_NORMAL);
02207 }
02208 
02209 void BumpNode::compile(SVMCompiler& compiler)
02210 {
02211     ShaderInput *center_in = input("SampleCenter");
02212     ShaderInput *dx_in = input("SampleX");
02213     ShaderInput *dy_in = input("SampleY");
02214 
02215     compiler.stack_assign(center_in);
02216     compiler.stack_assign(dx_in);
02217     compiler.stack_assign(dy_in);
02218 
02219     compiler.add_node(NODE_SET_BUMP, center_in->stack_offset, dx_in->stack_offset, dy_in->stack_offset);
02220 }
02221 
02222 void BumpNode::compile(OSLCompiler& compiler)
02223 {
02224     compiler.add(this, "node_bump");
02225 }
02226 
02227 CCL_NAMESPACE_END
02228