diff options
Diffstat (limited to 'intern/cycles/render/graph.cpp')
-rw-r--r-- | intern/cycles/render/graph.cpp | 110 |
1 files changed, 99 insertions, 11 deletions
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 9896eaba89b..e0537101247 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -33,7 +33,7 @@ ShaderInput::ShaderInput(ShaderNode *parent_, const char *name_, ShaderSocketTyp name = name_; type = type_; link = NULL; - value = make_float3(0, 0, 0); + value = make_float3(0.0f, 0.0f, 0.0f); stack_offset = SVM_STACK_INVALID; default_value = NONE; usage = USE_ALL; @@ -404,6 +404,36 @@ void ShaderGraph::remove_unneeded_nodes() } } } + else if(node->special_type == SHADER_SPECIAL_TYPE_EMISSION) { + EmissionNode *em = static_cast<EmissionNode*>(node); + + if(em->outputs[0]->links.size()) { + /* Black color or zero strength, remove node */ + if((!em->inputs[0]->link && em->inputs[0]->value == make_float3(0.0f, 0.0f, 0.0f)) || + (!em->inputs[1]->link && em->inputs[1]->value.x == 0.0f)) { + vector<ShaderInput*> inputs = em->outputs[0]->links; + + relink(em->inputs, inputs, NULL); + removed[em->id] = true; + any_node_removed = true; + } + } + } + else if(node->special_type == SHADER_SPECIAL_TYPE_BUMP) { + BumpNode *bump = static_cast<BumpNode*>(node); + + if(bump->outputs[0]->links.size()) { + /* Height input not connected */ + /* ToDo: Strength zero? */ + if(!bump->inputs[0]->link) { + vector<ShaderInput*> inputs = bump->outputs[0]->links; + + relink(bump->inputs, inputs, NULL); + removed[bump->id] = true; + any_node_removed = true; + } + } + } else if(node->special_type == SHADER_SPECIAL_TYPE_MIX_CLOSURE) { MixClosureNode *mix = static_cast<MixClosureNode*>(node); @@ -545,7 +575,7 @@ void ShaderGraph::clean() else delete node; } - + nodes = newnodes; } @@ -727,10 +757,18 @@ void ShaderGraph::bump_from_displacement() /* connect bump output to normal input nodes that aren't set yet. actually * this will only set the normal input to the geometry node that we created * and connected to all other normal inputs already. */ - foreach(ShaderNode *node, nodes) - foreach(ShaderInput *input, node->inputs) + foreach(ShaderNode *node, nodes) { + /* Don't connect normal to the bump node we're coming from, + * otherwise it'll be a cycle in graph. + */ + if(node == bump) { + continue; + } + foreach(ShaderInput *input, node->inputs) { if(!input->link && input->default_value == ShaderInput::NORMAL) connect(set_normal->output("Normal"), input); + } + } /* for displacement bump, clear the normal input in case the above loop * connected the setnormal out to the bump normalin */ @@ -825,6 +863,26 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight } } +int ShaderGraph::get_num_closures() +{ + int num_closures = 0; + foreach(ShaderNode *node, nodes) { + if(node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) { + BsdfNode *bsdf_node = static_cast<BsdfNode*>(node); + /* TODO(sergey): Make it more generic approach, maybe some utility + * macros like CLOSURE_IS_FOO()? + */ + if(CLOSURE_IS_BSSRDF(bsdf_node->closure)) + num_closures = num_closures + 3; + else if(CLOSURE_IS_GLASS(bsdf_node->closure)) + num_closures = num_closures + 2; + else + num_closures = num_closures + 1; + } + } + return num_closures; +} + void ShaderGraph::dump_graph(const char *filename) { FILE *fd = fopen(filename, "w"); @@ -836,29 +894,59 @@ void ShaderGraph::dump_graph(const char *filename) fprintf(fd, "digraph shader_graph {\n"); fprintf(fd, "ranksep=1.5\n"); + fprintf(fd, "rankdir=LR\n"); fprintf(fd, "splines=false\n"); foreach(ShaderNode *node, nodes) { fprintf(fd, "// NODE: %p\n", node); - fprintf(fd, - "\"%p\" [shape=record,label=\"%s\"]\n", - node, - node->name.c_str()); + fprintf(fd, "\"%p\" [shape=record,label=\"{", node); + if(node->inputs.size()) { + fprintf(fd, "{"); + foreach(ShaderInput *socket, node->inputs) { + if(socket != node->inputs[0]) { + fprintf(fd, "|"); + } + fprintf(fd, "<IN_%p>%s", socket, socket->name); + } + fprintf(fd, "}|"); + } + fprintf(fd, "%s", node->name.c_str()); + if(node->bump == SHADER_BUMP_CENTER) { + fprintf(fd, " (bump:center)"); + } + else if(node->bump == SHADER_BUMP_DX) { + fprintf(fd, " (bump:dx)"); + } + else if(node->bump == SHADER_BUMP_DY) { + fprintf(fd, " (bump:dy)"); + } + if(node->outputs.size()) { + fprintf(fd, "|{"); + foreach(ShaderOutput *socket, node->outputs) { + if(socket != node->outputs[0]) { + fprintf(fd, "|"); + } + fprintf(fd, "<OUT_%p>%s", socket, socket->name); + } + fprintf(fd, "}"); + } + fprintf(fd, "}\"]"); } foreach(ShaderNode *node, nodes) { foreach(ShaderOutput *output, node->outputs) { foreach(ShaderInput *input, output->links) { fprintf(fd, - "// CONNECTION: %p->%p (%s:%s)\n", + "// CONNECTION: OUT_%p->IN_%p (%s:%s)\n", output, input, output->name, input->name); fprintf(fd, - "\"%p\":s -> \"%p\":n [label=\"%s:%s\"]\n", + "\"%p\":\"OUT_%p\":e -> \"%p\":\"IN_%p\":w [label=\"\"]\n", output->parent, + output, input->parent, - output->name, input->name); + input); } } } |