1f4120937731fdec971ced12a49a478cd85c95ca
[blender.git] / intern / cycles / blender / blender_shader.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include "background.h"
20 #include "graph.h"
21 #include "light.h"
22 #include "nodes.h"
23 #include "scene.h"
24 #include "shader.h"
25
26 #include "blender_sync.h"
27 #include "blender_util.h"
28
29 #include "util_debug.h"
30
31 CCL_NAMESPACE_BEGIN
32
33 typedef map<void*, ShaderNode*> PtrNodeMap;
34 typedef pair<ShaderNode*, std::string> SocketPair;
35 typedef map<void*, SocketPair> PtrSockMap;
36
37 /* Find */
38
39 void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders)
40 {
41         Shader *shader = shader_map.find(id);
42
43         for(size_t i = 0; i < scene->shaders.size(); i++) {
44                 if(scene->shaders[i] == shader) {
45                         used_shaders.push_back(i);
46                         break;
47                 }
48         }
49 }
50
51 /* Graph */
52
53 static BL::NodeSocket get_node_input(BL::Node *b_group_node, BL::Node b_node, const string& name)
54 {
55         BL::Node::inputs_iterator b_in;
56
57         for(b_node.inputs.begin(b_in); b_in != b_node.inputs.end(); ++b_in) {
58                 if(b_in->name() == name) {
59                         if(b_group_node) {
60
61                                 BL::NodeTree b_ntree = BL::NodeGroup(*b_group_node).node_tree();
62                                 BL::NodeTree::links_iterator b_link;
63
64                                 for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
65                                         if(b_link->to_socket().ptr.data == b_in->ptr.data) {
66                                                 BL::Node::inputs_iterator b_gin;
67
68                                                 for(b_group_node->inputs.begin(b_gin); b_gin != b_group_node->inputs.end(); ++b_gin)
69                                                         if(b_gin->group_socket().ptr.data == b_link->from_socket().ptr.data)
70                                                                 return *b_gin;
71
72                                         }
73                                 }
74                         }
75
76                         return *b_in;
77                 }
78         }
79
80         assert(0);
81
82         return *b_in;
83 }
84
85 static BL::NodeSocket get_node_output(BL::Node b_node, const string& name)
86 {
87         BL::Node::outputs_iterator b_out;
88
89         for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
90                 if(b_out->name() == name)
91                         return *b_out;
92
93         assert(0);
94
95         return *b_out;
96 }
97
98 static float3 get_node_output_rgba(BL::Node b_node, const string& name)
99 {
100         BL::NodeSocketRGBA sock(get_node_output(b_node, name));
101         return get_float3(sock.default_value());
102 }
103
104 static float get_node_output_value(BL::Node b_node, const string& name)
105 {
106         BL::NodeSocketFloatNone sock(get_node_output(b_node, name));
107         return sock.default_value();
108 }
109
110 static ShaderNode *add_node(BL::BlendData b_data, ShaderGraph *graph, BL::Node *b_group_node, BL::ShaderNode b_node)
111 {
112         ShaderNode *node = NULL;
113
114         switch(b_node.type()) {
115                 /* not supported */
116                 case BL::ShaderNode::type_CAMERA: break;
117                 case BL::ShaderNode::type_COMBRGB: break;
118                 case BL::ShaderNode::type_CURVE_RGB: break;
119                 case BL::ShaderNode::type_CURVE_VEC: break;
120                 case BL::ShaderNode::type_GEOM: break;
121                 case BL::ShaderNode::type_HUE_SAT: break;
122                 case BL::ShaderNode::type_INVERT: break;
123                 case BL::ShaderNode::type_MATERIAL: break;
124                 case BL::ShaderNode::type_MATERIAL_EXT: break;
125                 case BL::ShaderNode::type_NORMAL: break;
126                 case BL::ShaderNode::type_OUTPUT: break;
127                 case BL::ShaderNode::type_SCRIPT: break;
128                 case BL::ShaderNode::type_SEPRGB: break;
129                 case BL::ShaderNode::type_SQUEEZE: break;
130                 case BL::ShaderNode::type_TEXTURE: break;
131                 case BL::ShaderNode::type_VALTORGB: break;
132                 /* handled outside this function */
133                 case BL::ShaderNode::type_GROUP: break;
134                 /* existing blender nodes */
135                 case BL::ShaderNode::type_RGB: {
136                         ColorNode *color = new ColorNode();
137                         color->value = get_node_output_rgba(b_node, "Color");
138                         node = color;
139                         break;
140                 }
141                 case BL::ShaderNode::type_VALUE: {
142                         ValueNode *value = new ValueNode();
143                         value->value = get_node_output_value(b_node, "Value");
144                         node = value;
145                         break;
146                 }
147                 case BL::ShaderNode::type_MIX_RGB: {
148                         BL::ShaderNodeMixRGB b_mix_node(b_node);
149                         MixNode *mix = new MixNode();
150                         mix->type = MixNode::type_enum[b_mix_node.blend_type()];
151                         node = mix;
152                         break;
153                 }
154                 case BL::ShaderNode::type_RGBTOBW: {
155                         node = new ConvertNode(SHADER_SOCKET_COLOR, SHADER_SOCKET_FLOAT);
156                         break;
157                 }
158                 case BL::ShaderNode::type_MATH: {
159                         BL::ShaderNodeMath b_math_node(b_node);
160                         MathNode *math = new MathNode();
161                         math->type = MathNode::type_enum[b_math_node.operation()];
162                         node = math;
163                         break;
164                 }
165                 case BL::ShaderNode::type_VECT_MATH: {
166                         BL::ShaderNodeVectorMath b_vector_math_node(b_node);
167                         VectorMathNode *vmath = new VectorMathNode();
168                         vmath->type = VectorMathNode::type_enum[b_vector_math_node.operation()];
169                         node = vmath;
170                         break;
171                 }
172                 case BL::ShaderNode::type_MAPPING: {
173                         BL::ShaderNodeMapping b_mapping_node(b_node);
174                         MappingNode *mapping = new MappingNode();
175                         mapping->translation = get_float3(b_mapping_node.location());
176                         mapping->rotation = get_float3(b_mapping_node.rotation());
177                         mapping->scale = get_float3(b_mapping_node.scale());
178                         node = mapping;
179                         break;
180                 }
181
182                 /* new nodes */
183                 case BL::ShaderNode::type_OUTPUT_MATERIAL:
184                 case BL::ShaderNode::type_OUTPUT_WORLD:
185                 case BL::ShaderNode::type_OUTPUT_LAMP: {
186                         node = graph->output();
187                         break;
188                 }
189                 case BL::ShaderNode::type_FRESNEL: {
190                         node = new FresnelNode();
191                         break;
192                 }
193                 case BL::ShaderNode::type_BLEND_WEIGHT: {
194                         node = new BlendWeightNode();
195                         break;
196                 }
197                 case BL::ShaderNode::type_ADD_SHADER: {
198                         node = new AddClosureNode();
199                         break;
200                 }
201                 case BL::ShaderNode::type_MIX_SHADER: {
202                         node = new MixClosureNode();
203                         break;
204                 }
205                 case BL::ShaderNode::type_ATTRIBUTE: {
206                         AttributeNode *attr = new AttributeNode();
207                         attr->attribute = "";
208                         node = attr;
209                         break;
210                 }
211                 case BL::ShaderNode::type_BACKGROUND: {
212                         node = new BackgroundNode();
213                         break;
214                 }
215                 case BL::ShaderNode::type_HOLDOUT: {
216                         node = new HoldoutNode();
217                         break;
218                 }
219                 case BL::ShaderNode::type_BSDF_ANISOTROPIC: {
220                         node = new WardBsdfNode();
221                         break;
222                 }
223                 case BL::ShaderNode::type_BSDF_DIFFUSE: {
224                         node = new DiffuseBsdfNode();
225                         break;
226                 }
227                 case BL::ShaderNode::type_BSDF_GLOSSY: {
228                         BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
229                         GlossyBsdfNode *glossy = new GlossyBsdfNode();
230
231                         switch(b_glossy_node.distribution()) {
232                                 case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
233                                         glossy->distribution = ustring("Sharp");
234                                         break;
235                                 case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
236                                         glossy->distribution = ustring("Beckmann");
237                                         break;
238                                 case BL::ShaderNodeBsdfGlossy::distribution_GGX:
239                                         glossy->distribution = ustring("GGX");
240                                         break;
241                         }
242                         node = glossy;
243                         break;
244                 }
245                 case BL::ShaderNode::type_BSDF_GLASS: {
246                         BL::ShaderNodeBsdfGlass b_glass_node(b_node);
247                         GlassBsdfNode *glass = new GlassBsdfNode();
248                         switch(b_glass_node.distribution()) {
249                                 case BL::ShaderNodeBsdfGlass::distribution_SHARP:
250                                         glass->distribution = ustring("Sharp");
251                                         break;
252                                 case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
253                                         glass->distribution = ustring("Beckmann");
254                                         break;
255                                 case BL::ShaderNodeBsdfGlass::distribution_GGX:
256                                         glass->distribution = ustring("GGX");
257                                         break;
258                         }
259                         node = glass;
260                         break;
261                 }
262                 case BL::ShaderNode::type_BSDF_TRANSLUCENT: {
263                         node = new TranslucentBsdfNode();
264                         break;
265                 }
266                 case BL::ShaderNode::type_BSDF_TRANSPARENT: {
267                         node = new TransparentBsdfNode();
268                         break;
269                 }
270                 case BL::ShaderNode::type_BSDF_VELVET: {
271                         node = new VelvetBsdfNode();
272                         break;
273                 }
274                 case BL::ShaderNode::type_EMISSION: {
275                         node = new EmissionNode();
276                         break;
277                 }
278                 case BL::ShaderNode::type_GEOMETRY: {
279                         node = new GeometryNode();
280                         break;
281                 }
282                 case BL::ShaderNode::type_LIGHT_PATH: {
283                         node = new LightPathNode();
284                         break;
285                 }
286                 case BL::ShaderNode::type_TEX_IMAGE: {
287                         BL::ShaderNodeTexImage b_image_node(b_node);
288                         BL::Image b_image(b_image_node.image());
289                         ImageTextureNode *image = new ImageTextureNode();
290                         /* todo: handle generated/builtin images */
291                         if(b_image)
292                                 image->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
293                         image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
294                         node = image;
295                         break;
296                 }
297                 case BL::ShaderNode::type_TEX_ENVIRONMENT: {
298                         BL::ShaderNodeTexEnvironment b_env_node(b_node);
299                         BL::Image b_image(b_env_node.image());
300                         EnvironmentTextureNode *env = new EnvironmentTextureNode();
301                         if(b_image)
302                                 env->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
303                         env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
304                         node = env;
305                         break;
306                 }
307                 case BL::ShaderNode::type_TEX_NOISE: {
308                         node = new NoiseTextureNode();
309                         break;
310                 }
311                 case BL::ShaderNode::type_TEX_BLEND: {
312                         BL::ShaderNodeTexBlend b_blend_node(b_node);
313                         BlendTextureNode *blend = new BlendTextureNode();
314                         blend->progression = BlendTextureNode::progression_enum[(int)b_blend_node.progression()];
315                         blend->axis = BlendTextureNode::axis_enum[(int)b_blend_node.axis()];
316                         node = blend;
317                         break;
318                 }
319                 case BL::ShaderNode::type_TEX_VORONOI: {
320                         BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
321                         VoronoiTextureNode *voronoi = new VoronoiTextureNode();
322                         voronoi->distance_metric = VoronoiTextureNode::distance_metric_enum[(int)b_voronoi_node.distance_metric()];
323                         voronoi->coloring = VoronoiTextureNode::coloring_enum[(int)b_voronoi_node.coloring()];
324                         node = voronoi;
325                         break;
326                 }
327                 case BL::ShaderNode::type_TEX_MAGIC: {
328                         BL::ShaderNodeTexMagic b_magic_node(b_node);
329                         MagicTextureNode *magic = new MagicTextureNode();
330                         magic->depth = b_magic_node.turbulence_depth();
331                         node = magic;
332                         break;
333                 }
334                 case BL::ShaderNode::type_TEX_MARBLE: {
335                         BL::ShaderNodeTexMarble b_marble_node(b_node);
336                         MarbleTextureNode *marble = new MarbleTextureNode();
337                         marble->depth = b_marble_node.turbulence_depth();
338                         marble->basis = MarbleTextureNode::basis_enum[(int)b_marble_node.noise_basis()];
339                         marble->type = MarbleTextureNode::type_enum[(int)b_marble_node.marble_type()];
340                         marble->wave = MarbleTextureNode::wave_enum[(int)b_marble_node.wave_type()];
341                         marble->hard = b_marble_node.noise_type() == BL::ShaderNodeTexMarble::noise_type_HARD;
342                         node = marble;
343                         break;
344                 }
345                 case BL::ShaderNode::type_TEX_CLOUDS: {
346                         BL::ShaderNodeTexClouds b_clouds_node(b_node);
347                         CloudsTextureNode *clouds = new CloudsTextureNode();
348                         clouds->depth = b_clouds_node.turbulence_depth();
349                         clouds->basis = CloudsTextureNode::basis_enum[(int)b_clouds_node.noise_basis()];
350                         clouds->hard = b_clouds_node.noise_type() == BL::ShaderNodeTexClouds::noise_type_HARD;
351                         node = clouds;
352                         break;
353                 }
354                 case BL::ShaderNode::type_TEX_WOOD: {
355                         BL::ShaderNodeTexWood b_wood_node(b_node);
356                         WoodTextureNode *wood = new WoodTextureNode();
357                         wood->type = WoodTextureNode::type_enum[(int)b_wood_node.wood_type()];
358                         wood->basis = WoodTextureNode::basis_enum[(int)b_wood_node.noise_basis()];
359                         wood->hard = b_wood_node.noise_type() == BL::ShaderNodeTexWood::noise_type_HARD;
360                         wood->wave = WoodTextureNode::wave_enum[(int)b_wood_node.wave_type()];
361                         node = wood;
362                         break;
363                 }
364                 case BL::ShaderNode::type_TEX_MUSGRAVE: {
365                         BL::ShaderNodeTexMusgrave b_musgrave_node(b_node);
366                         MusgraveTextureNode *musgrave = new MusgraveTextureNode();
367                         musgrave->type = MusgraveTextureNode::type_enum[(int)b_musgrave_node.musgrave_type()];
368                         musgrave->basis = MusgraveTextureNode::basis_enum[(int)b_musgrave_node.noise_basis()];
369                         node = musgrave;
370                         break;
371                 }
372                 case BL::ShaderNode::type_TEX_STUCCI: {
373                         BL::ShaderNodeTexStucci b_stucci_node(b_node);
374                         StucciTextureNode *stucci = new StucciTextureNode();
375                         stucci->type = StucciTextureNode::type_enum[(int)b_stucci_node.stucci_type()];
376                         stucci->basis = StucciTextureNode::basis_enum[(int)b_stucci_node.noise_basis()];
377                         stucci->hard = b_stucci_node.noise_type() == BL::ShaderNodeTexStucci::noise_type_HARD;
378                         node = stucci;
379                         break;
380                 }
381                 case BL::ShaderNode::type_TEX_DISTORTED_NOISE: {
382                         BL::ShaderNodeTexDistortedNoise b_distnoise_node(b_node);
383                         DistortedNoiseTextureNode *distnoise = new DistortedNoiseTextureNode();
384                         distnoise->basis = DistortedNoiseTextureNode::basis_enum[(int)b_distnoise_node.noise_basis()];
385                         distnoise->distortion_basis = DistortedNoiseTextureNode::basis_enum[(int)b_distnoise_node.noise_distortion()];
386                         node = distnoise;
387                         break;
388                 }
389                 case BL::ShaderNode::type_TEX_COORD: {
390                         node = new TextureCoordinateNode();;
391                         break;
392                 }
393                 case BL::ShaderNode::type_TEX_SKY: {
394                         BL::ShaderNodeTexSky b_sky_node(b_node);
395                         SkyTextureNode *sky = new SkyTextureNode();
396                         sky->sun_direction = get_float3(b_sky_node.sun_direction());
397                         sky->turbidity = b_sky_node.turbidity();
398                         node = sky;
399                         break;
400                 }
401         }
402
403         if(node && node != graph->output())
404                 graph->add(node);
405
406         return node;
407 }
408
409 static const char *node_socket_map_name(const char *name)
410 {
411         if(strstr(name, "Shader")) {
412                 if(strcmp(name, "Shader") == 0)
413                         return "Closure";
414                 if(strcmp(name, "Shader1") == 0)
415                         return "Closure1";
416                 if(strcmp(name, "Shader2") == 0)
417                         return "Closure2";
418         }
419
420         return name;
421 }
422
423 static void add_nodes(BL::BlendData b_data, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::Node *b_group_node, PtrSockMap& sockets_map)
424 {
425         /* add nodes */
426         BL::ShaderNodeTree::nodes_iterator b_node;
427         PtrNodeMap node_map;
428         map<void*, PtrSockMap> node_groups;
429
430         for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
431                 if(b_node->is_a(&RNA_NodeGroup)) {
432                         BL::NodeGroup b_gnode(*b_node);
433                         BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
434
435                         node_groups[b_node->ptr.data] = PtrSockMap();
436                         add_nodes(b_data, graph, b_group_ntree, &b_gnode, node_groups[b_node->ptr.data]);
437                 }
438                 else {
439                         ShaderNode *node = add_node(b_data, graph, b_group_node, BL::ShaderNode(*b_node));
440
441                         if(node) {
442                                 BL::Node::inputs_iterator b_input;
443                                 BL::Node::outputs_iterator b_output;
444
445                                 node_map[b_node->ptr.data] = node;
446
447                                 for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
448                                         ShaderInput *input = node->input(node_socket_map_name(b_input->name().c_str()));
449                                         BL::NodeSocket sock(get_node_input(b_group_node, *b_node, b_input->name()));
450
451                                         assert(input);
452
453                                         /* copy values for non linked inputs */
454                                         switch(input->type) {
455                                                 case SHADER_SOCKET_FLOAT: {
456                                                         BL::NodeSocketFloatNone value_sock(sock);
457                                                         input->set(value_sock.default_value());
458                                                         break;
459                                                 }
460                                                 case SHADER_SOCKET_COLOR: {
461                                                         BL::NodeSocketRGBA rgba_sock(sock);
462                                                         input->set(get_float3(rgba_sock.default_value()));
463                                                         break;
464                                                 }
465                                                 case SHADER_SOCKET_NORMAL:
466                                                 case SHADER_SOCKET_POINT:
467                                                 case SHADER_SOCKET_VECTOR: {
468                                                         BL::NodeSocketVectorNone vec_sock(sock);
469                                                         input->set(get_float3(vec_sock.default_value()));
470                                                         break;
471                                                 }
472                                                 case SHADER_SOCKET_CLOSURE:
473                                                         break;
474                                         }
475                                 }
476                         }
477                 }
478         }
479
480         /* connect nodes */
481         BL::NodeTree::links_iterator b_link;
482
483         for(b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
484                 /* get blender link data */
485                 BL::Node b_from_node = b_link->from_node();
486                 BL::Node b_to_node = b_link->to_node();
487
488                 BL::NodeSocket b_from_sock = b_link->from_socket();
489                 BL::NodeSocket b_to_sock = b_link->to_socket();
490
491                 /* if link with group socket, add to map so we can connect it later */
492                 if(b_group_node) {
493                         if(!b_from_node) {
494                                 sockets_map[b_from_sock.ptr.data] =
495                                         SocketPair(node_map[b_to_node.ptr.data], b_to_sock.name());
496
497                                 continue;
498                         }
499                         else if(!b_to_node) {
500                                 sockets_map[b_to_sock.ptr.data] =
501                                         SocketPair(node_map[b_from_node.ptr.data], b_from_sock.name());
502
503                                 continue;
504                         }
505                 }
506
507                 ShaderNode *from_node, *to_node;
508                 string from_name, to_name;
509
510                 /* from sock */
511                 if(b_from_node.is_a(&RNA_NodeGroup)) {
512                         /* group node */
513                         BL::NodeSocket group_sock = b_from_sock.group_socket();
514                         SocketPair& pair = node_groups[b_from_node.ptr.data][group_sock.ptr.data];
515
516                         from_node = pair.first;
517                         from_name = pair.second;
518                 }
519                 else {
520                         /* regular node */
521                         from_node = node_map[b_from_node.ptr.data];
522                         from_name = b_from_sock.name();
523                 }
524
525                 /* to sock */
526                 if(b_to_node.is_a(&RNA_NodeGroup)) {
527                         /* group node */
528                         BL::NodeSocket group_sock = b_to_sock.group_socket();
529                         SocketPair& pair = node_groups[b_to_node.ptr.data][group_sock.ptr.data];
530
531                         to_node = pair.first;
532                         to_name = pair.second;
533                 }
534                 else {
535                         /* regular node */
536                         to_node = node_map[b_to_node.ptr.data];
537                         to_name = b_to_sock.name();
538                 }
539
540                 /* in case of groups there may not actually be a node inside the group
541                    that the group socket connects to, so from_node or to_node may be NULL */
542                 if(from_node && to_node)
543                         graph->connect(from_node->output(node_socket_map_name(from_name.c_str())), to_node->input(node_socket_map_name(to_name.c_str())));
544         }
545 }
546
547 /* Sync Materials */
548
549 void BlenderSync::sync_materials()
550 {
551         shader_map.set_default(scene->shaders[scene->default_surface]);
552
553         /* material loop */
554         BL::BlendData::materials_iterator b_mat;
555
556         for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
557                 Shader *shader;
558                 
559                 /* test if we need to sync */
560                 if(shader_map.sync(&shader, *b_mat)) {
561                         ShaderGraph *graph = new ShaderGraph();
562
563                         shader->name = b_mat->name();
564
565                         /* create nodes */
566                         if(b_mat->use_nodes() && b_mat->node_tree()) {
567                                 PtrSockMap sock_to_node;
568                                 BL::ShaderNodeTree b_ntree(b_mat->node_tree());
569
570                                 add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
571                         }
572                         else {
573                                 ShaderNode *closure, *out;
574
575                                 closure = graph->add(new DiffuseBsdfNode());
576                                 closure->input("Color")->value = get_float3(b_mat->diffuse_color());
577                                 out = graph->output();
578
579                                 graph->connect(closure->output("BSDF"), out->input("Surface"));
580                         }
581
582                         shader->set_graph(graph);
583                         shader->tag_update(scene);
584                 }
585         }
586 }
587
588 /* Sync World */
589
590 void BlenderSync::sync_world()
591 {
592         Background *background = scene->background;
593         Background prevbackground = *background;
594
595         BL::World b_world = b_scene.world();
596
597         if(world_recalc || b_world.ptr.data != world_map) {
598                 Shader *shader = scene->shaders[scene->default_background];
599                 ShaderGraph *graph = new ShaderGraph();
600
601                 /* create nodes */
602                 if(b_world && b_world.use_nodes() && b_world.node_tree()) {
603                         PtrSockMap sock_to_node;
604                         BL::ShaderNodeTree b_ntree(b_world.node_tree());
605
606                         add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
607                 }
608                 else if(b_world) {
609                         ShaderNode *closure, *out;
610
611                         closure = graph->add(new BackgroundNode());
612                         closure->input("Color")->value = get_float3(b_world.horizon_color());
613                         out = graph->output();
614
615                         graph->connect(closure->output("Background"), out->input("Surface"));
616                 }
617
618                 shader->set_graph(graph);
619                 shader->tag_update(scene);
620         }
621
622         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
623         background->transparent = get_boolean(cscene, "film_transparent");
624
625         if(background->modified(prevbackground))
626                 background->tag_update(scene);
627
628         world_map = b_world.ptr.data;
629         world_recalc = false;
630 }
631
632 /* Sync Lamps */
633
634 void BlenderSync::sync_lamps()
635 {
636         shader_map.set_default(scene->shaders[scene->default_light]);
637
638         /* lamp loop */
639         BL::BlendData::lamps_iterator b_lamp;
640
641         for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) {
642                 Shader *shader;
643                 
644                 /* test if we need to sync */
645                 if(shader_map.sync(&shader, *b_lamp)) {
646                         ShaderGraph *graph = new ShaderGraph();
647
648                         /* create nodes */
649                         if(b_lamp->use_nodes() && b_lamp->node_tree()) {
650                                 shader->name = b_lamp->name();
651
652                                 PtrSockMap sock_to_node;
653                                 BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
654
655                                 add_nodes(b_data, graph, b_ntree, NULL, sock_to_node);
656                         }
657                         else {
658                                 ShaderNode *closure, *out;
659
660                                 closure = graph->add(new EmissionNode());
661                                 closure->input("Color")->value = get_float3(b_lamp->color());
662                                 closure->input("Strength")->value.x = b_lamp->energy()*10.0f;
663                                 out = graph->output();
664
665                                 graph->connect(closure->output("Emission"), out->input("Surface"));
666                         }
667
668                         shader->set_graph(graph);
669                         shader->tag_update(scene);
670                 }
671         }
672 }
673
674 void BlenderSync::sync_shaders()
675 {
676         shader_map.pre_sync();
677
678         sync_world();
679         sync_lamps();
680         sync_materials();
681
682         /* false = don't delete unused shaders, not supported */
683         shader_map.post_sync(false);
684 }
685
686 CCL_NAMESPACE_END
687