87
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value)
88
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float value, int usage)
89
90
ShaderInput *input = new ShaderInput(this, name, type);
90
91
input->value.x = value;
91
93
inputs.push_back(input);
95
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value)
97
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, float3 value, int usage)
97
99
ShaderInput *input = new ShaderInput(this, name, type);
98
100
input->value = value;
101
input->usage = usage;
99
102
inputs.push_back(input);
103
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, bool osl_only)
106
ShaderInput *ShaderNode::add_input(const char *name, ShaderSocketType type, ShaderInput::DefaultValue value, int usage)
105
108
ShaderInput *input = add_input(name, type);
106
109
input->default_value = value;
107
input->osl_only = osl_only;
110
input->usage = usage;
120
123
foreach(ShaderInput *input, inputs) {
121
124
if(!input->link) {
122
125
if(input->default_value == ShaderInput::TEXTURE_GENERATED)
123
attributes->add(Attribute::STD_GENERATED);
126
attributes->add(ATTR_STD_GENERATED);
124
127
else if(input->default_value == ShaderInput::TEXTURE_UV)
125
attributes->add(Attribute::STD_UV);
128
attributes->add(ATTR_STD_UV);
180
183
assert(from && to);
183
fprintf(stderr, "ShaderGraph connect: input already connected.\n");
186
fprintf(stderr, "Cycles shader graph connect: input already connected.\n");
187
190
if(from->type != to->type) {
188
191
/* for closures we can't do automatic conversion */
189
192
if(from->type == SHADER_SOCKET_CLOSURE || to->type == SHADER_SOCKET_CLOSURE) {
190
fprintf(stderr, "ShaderGraph connect: can only connect closure to closure.\n");
193
fprintf(stderr, "Cycles shader graph connect: can only connect closure to closure "
194
"(ShaderNode:%s, ShaderOutput:%s , type:%d -> to ShaderNode:%s, ShaderInput:%s, type:%d).\n",
195
from->parent->name.c_str(), from->name, (int)from->type,
196
to->parent->name.c_str(), to->name, (int)to->type);
215
221
from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
218
void ShaderGraph::finalize(bool do_bump, bool do_osl)
224
void ShaderGraph::finalize(bool do_bump, bool do_osl, bool do_multi_transform)
220
226
/* before compiling, the shader graph may undergo a number of modifications.
221
227
* currently we set default geometry shader inputs, and create automatic bump
227
233
default_inputs(do_osl);
229
237
bump_from_displacement();
239
if(do_multi_transform) {
240
ShaderInput *surface_in = output()->input("Surface");
241
ShaderInput *volume_in = output()->input("Volume");
243
/* todo: make this work when surface and volume closures are tangled up */
246
transform_multi_closure(surface_in->link->parent, NULL, false);
248
transform_multi_closure(volume_in->link->parent, NULL, true);
231
251
finalized = true;
295
315
void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
297
317
foreach(ShaderNode *node, nodes) {
298
ProxyNode *proxy = dynamic_cast<ProxyNode*>(node);
318
if (node->special_type == SHADER_SPECIAL_TYPE_PROXY) {
319
ProxyNode *proxy = static_cast<ProxyNode*>(node);
300
320
ShaderInput *input = proxy->inputs[0];
301
321
ShaderOutput *output = proxy->outputs[0];
321
341
/* transfer the default input value to the target socket */
322
342
to->set(input->value);
343
to->set(input->value_string);
326
347
removed[proxy->id] = true;
350
/* remove useless mix closures nodes */
351
if(node->special_type == SHADER_SPECIAL_TYPE_MIX_CLOSURE) {
352
MixClosureNode *mix = static_cast<MixClosureNode*>(node);
353
if(mix->outputs[0]->links.size() && mix->inputs[1]->link == mix->inputs[2]->link) {
354
ShaderOutput *output = mix->inputs[1]->link;
355
vector<ShaderInput*> inputs = mix->outputs[0]->links;
357
foreach(ShaderInput *sock, mix->inputs)
361
foreach(ShaderInput *input, inputs) {
364
connect(output, input);
355
395
void ShaderGraph::clean()
357
397
/* we do two things here: find cycles and break them, and remove unused
358
nodes that don't feed into the output. how cycles are broken is
359
undefined, they are invalid input, the important thing is to not crash */
398
* nodes that don't feed into the output. how cycles are broken is
399
* undefined, they are invalid input, the important thing is to not crash */
361
401
vector<bool> removed(nodes.size(), false);
362
402
vector<bool> visited(nodes.size(), false);
379
419
/* break cycles */
380
420
break_cycles(output(), visited, on_stack);
422
/* disconnect unused nodes */
423
foreach(ShaderNode *node, nodes) {
424
if(!visited[node->id]) {
425
foreach(ShaderInput *to, node->inputs) {
426
ShaderOutput *from = to->link;
430
from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
382
436
/* remove unused nodes */
383
437
foreach(ShaderNode *node, nodes) {
384
438
if(visited[node->id])
401
455
foreach(ShaderNode *node, nodes) {
402
456
foreach(ShaderInput *input, node->inputs) {
403
if(!input->link && !(input->osl_only && !do_osl)) {
457
if(!input->link && ((input->usage & ShaderInput::USE_SVM) || do_osl)) {
404
458
if(input->default_value == ShaderInput::TEXTURE_GENERATED) {
406
460
texco = new TextureCoordinateNode();
504
void ShaderGraph::refine_bump_nodes()
506
/* we transverse the node graph looking for bump nodes, when we find them,
507
* like in bump_from_displacement(), we copy the sub-graph defined from "bump"
508
* input to the inputs "center","dx" and "dy" What is in "bump" input is moved
509
* to "center" input. */
511
foreach(ShaderNode *node, nodes) {
512
if(node->name == ustring("bump") && node->input("Height")->link) {
513
ShaderInput *bump_input = node->input("Height");
514
set<ShaderNode*> nodes_bump;
516
/* make 2 extra copies of the subgraph defined in Bump input */
517
map<ShaderNode*, ShaderNode*> nodes_dx;
518
map<ShaderNode*, ShaderNode*> nodes_dy;
520
/* find dependencies for the given input */
521
find_dependencies(nodes_bump, bump_input );
523
copy_nodes(nodes_bump, nodes_dx);
524
copy_nodes(nodes_bump, nodes_dy);
526
/* mark nodes to indicate they are use for bump computation, so
527
that any texture coordinates are shifted by dx/dy when sampling */
528
foreach(ShaderNode *node, nodes_bump)
529
node->bump = SHADER_BUMP_CENTER;
530
foreach(NodePair& pair, nodes_dx)
531
pair.second->bump = SHADER_BUMP_DX;
532
foreach(NodePair& pair, nodes_dy)
533
pair.second->bump = SHADER_BUMP_DY;
535
ShaderOutput *out = bump_input->link;
536
ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name);
537
ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name);
539
connect(out_dx, node->input("SampleX"));
540
connect(out_dy, node->input("SampleY"));
542
/* add generated nodes */
543
foreach(NodePair& pair, nodes_dx)
545
foreach(NodePair& pair, nodes_dy)
548
/* connect what is conected is bump to samplecenter input*/
549
connect(out , node->input("SampleCenter"));
551
/* bump input is just for connectivity purpose for the graph input,
552
* we reconected this input to samplecenter, so lets disconnect it
554
disconnect(bump_input);
444
559
void ShaderGraph::bump_from_displacement()
446
561
/* generate bump mapping automatically from displacement. bump mapping is
475
590
copy_nodes(nodes_displace, nodes_dy);
477
592
/* mark nodes to indicate they are use for bump computation, so
478
that any texture coordinates are shifted by dx/dy when sampling */
593
* that any texture coordinates are shifted by dx/dy when sampling */
479
594
foreach(NodePair& pair, nodes_center)
480
595
pair.second->bump = SHADER_BUMP_CENTER;
481
596
foreach(NodePair& pair, nodes_dx)
483
598
foreach(NodePair& pair, nodes_dy)
484
599
pair.second->bump = SHADER_BUMP_DY;
601
/* add set normal node and connect the bump normal ouput to the set normal
602
* output, so it can finally set the shader normal, note we are only doing
603
* this for bump from displacement, this will be the only bump allowed to
604
* overwrite the shader normal */
605
ShaderNode *set_normal = add(new SetNormalNode());
486
607
/* add bump node and connect copied graphs to it */
487
608
ShaderNode *bump = add(new BumpNode());
494
615
connect(out_center, bump->input("SampleCenter"));
495
616
connect(out_dx, bump->input("SampleX"));
496
617
connect(out_dy, bump->input("SampleY"));
619
/* connect the bump out to the set normal in: */
620
connect(bump->output("Normal"), set_normal->input("Direction"));
498
622
/* connect bump output to normal input nodes that aren't set yet. actually
499
this will only set the normal input to the geometry node that we created
500
and connected to all other normal inputs already. */
623
* this will only set the normal input to the geometry node that we created
624
* and connected to all other normal inputs already. */
501
625
foreach(ShaderNode *node, nodes)
502
626
foreach(ShaderInput *input, node->inputs)
503
627
if(!input->link && input->default_value == ShaderInput::NORMAL)
504
connect(bump->output("Normal"), input);
628
connect(set_normal->output("Normal"), input);
630
/* for displacement bump, clear the normal input in case the above loop
631
* connected the setnormal out to the bump normalin */
632
ShaderInput *bump_normal_in = bump->input("NormalIn");
634
bump_normal_in->link = NULL;
506
636
/* finally, add the copied nodes to the graph. we can't do this earlier
507
because we would create dependency cycles in the above loop */
637
* because we would create dependency cycles in the above loop */
508
638
foreach(NodePair& pair, nodes_center)
509
639
add(pair.second);
510
640
foreach(NodePair& pair, nodes_dx)
513
643
add(pair.second);
646
void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume)
648
/* for SVM in multi closure mode, this transforms the shader mix/add part of
649
* the graph into nodes that feed weights into closure nodes. this is too
650
* avoid building a closure tree and then flattening it, and instead write it
651
* directly to an array */
653
if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
654
ShaderInput *fin = node->input("Fac");
655
ShaderInput *cl1in = node->input("Closure1");
656
ShaderInput *cl2in = node->input("Closure2");
657
ShaderOutput *weight1_out, *weight2_out;
660
/* mix closure: add node to mix closure weights */
661
ShaderNode *mix_node = add(new MixClosureWeightNode());
662
ShaderInput *fac_in = mix_node->input("Fac");
663
ShaderInput *weight_in = mix_node->input("Weight");
666
connect(fin->link, fac_in);
668
fac_in->value = fin->value;
671
connect(weight_out, weight_in);
673
weight1_out = mix_node->output("Weight1");
674
weight2_out = mix_node->output("Weight2");
677
/* add closure: just pass on any weights */
678
weight1_out = weight_out;
679
weight2_out = weight_out;
683
transform_multi_closure(cl1in->link->parent, weight1_out, volume);
685
transform_multi_closure(cl2in->link->parent, weight2_out, volume);
688
ShaderInput *weight_in = node->input((volume)? "VolumeMixWeight": "SurfaceMixWeight");
690
/* not a closure node? */
694
/* already has a weight connected to it? add weights */
695
if(weight_in->link || weight_in->value.x != 0.0f) {
696
ShaderNode *math_node = add(new MathNode());
697
ShaderInput *value1_in = math_node->input("Value1");
698
ShaderInput *value2_in = math_node->input("Value2");
701
connect(weight_in->link, value1_in);
703
value1_in->value = weight_in->value;
706
connect(weight_out, value2_in);
708
value2_in->value.x = 1.0f;
710
weight_out = math_node->output("Value");
712
disconnect(weight_in);
715
/* connected to closure mix weight */
717
connect(weight_out, weight_in);
719
weight_in->value.x += 1.0f;
516
723
CCL_NAMESPACE_END