diff options
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/graph.cpp | 23 | ||||
-rw-r--r-- | intern/cycles/render/osl.cpp | 25 | ||||
-rw-r--r-- | intern/cycles/render/shader.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/svm.cpp | 52 | ||||
-rw-r--r-- | intern/cycles/render/svm.h | 1 |
5 files changed, 60 insertions, 43 deletions
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 6e795ef896a..57256ceecd3 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -856,27 +856,8 @@ void ShaderGraph::bump_from_displacement() /* connect the bump out to the set normal in: */ connect(bump->output("Normal"), set_normal->input("Direction")); - /* 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) { - /* 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->flags() & SocketType::LINK_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 */ - ShaderInput *bump_normal_in = bump->input("Normal"); - if(bump_normal_in) - bump_normal_in->link = NULL; + /* connect to output node */ + connect(set_normal->output("Normal"), output()->input("Normal")); /* finally, add the copied nodes to the graph. we can't do this earlier * because we would create dependency cycles in the above loop */ diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 8d5e29579c2..f83aab47e84 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -609,7 +609,7 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input) return true; if(input->name() == "Displacement" && current_type != SHADER_TYPE_DISPLACEMENT) return true; - if(input->name() == "Normal") + if(input->name() == "Normal" && current_type != SHADER_TYPE_BUMP) return true; } else if(node->special_type == SHADER_SPECIAL_TYPE_BUMP) { @@ -684,6 +684,8 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) ss->Shader("surface", name, id(node).c_str()); else if(current_type == SHADER_TYPE_DISPLACEMENT) ss->Shader("displacement", name, id(node).c_str()); + else if(current_type == SHADER_TYPE_BUMP) + ss->Shader("displacement", name, id(node).c_str()); else assert(0); @@ -1055,6 +1057,12 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph generate_nodes(dependencies); output->compile(*this); } + else if(type == SHADER_TYPE_BUMP) { + /* generate bump shader */ + find_dependencies(dependencies, output->input("Normal")); + generate_nodes(dependencies); + output->compile(*this); + } else if(type == SHADER_TYPE_VOLUME) { /* generate volume shader */ find_dependencies(dependencies, output->input("Volume")); @@ -1116,10 +1124,10 @@ void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader) if(shader->used && graph && output->input("Surface")->link) { shader->osl_surface_ref = compile_type(shader, shader->graph, SHADER_TYPE_SURFACE); - if(shader->graph_bump) - shader->osl_surface_bump_ref = compile_type(shader, shader->graph_bump, SHADER_TYPE_SURFACE); + if(shader->graph_bump && shader->displacement_method != DISPLACE_TRUE) + shader->osl_surface_bump_ref = compile_type(shader, shader->graph_bump, SHADER_TYPE_BUMP); else - shader->osl_surface_bump_ref = shader->osl_surface_ref; + shader->osl_surface_bump_ref = OSL::ShaderGroupRef(); shader->has_surface = true; } @@ -1146,15 +1154,10 @@ void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader) } /* push state to array for lookup */ - if(shader->displacement_method == DISPLACE_TRUE || !shader->graph_bump) { - og->surface_state.push_back(shader->osl_surface_ref); - } - else { - og->surface_state.push_back(shader->osl_surface_bump_ref); - } - + og->surface_state.push_back(shader->osl_surface_ref); og->volume_state.push_back(shader->osl_volume_ref); og->displacement_state.push_back(shader->osl_displacement_ref); + og->bump_state.push_back(shader->osl_surface_bump_ref); } #else diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 1876791c6e8..165a316ea76 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -407,6 +407,8 @@ void ShaderManager::device_update_common(Device *device, flag |= SD_VOLUME_CUBIC; if(shader->graph_bump) flag |= SD_HAS_BUMP; + if(shader->displacement_method != DISPLACE_BUMP) + flag |= SD_HAS_DISPLACEMENT; /* shader with bump mapping */ if(shader->displacement_method != DISPLACE_TRUE && shader->graph_bump) diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index be87b35dbbc..069c3e3043a 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -146,9 +146,8 @@ int SVMCompiler::stack_size(SocketType::Type type) return size; } -int SVMCompiler::stack_find_offset(SocketType::Type type) +int SVMCompiler::stack_find_offset(int size) { - int size = stack_size(type); int offset = -1; /* find free space in stack & mark as used */ @@ -175,6 +174,11 @@ int SVMCompiler::stack_find_offset(SocketType::Type type) return 0; } +int SVMCompiler::stack_find_offset(SocketType::Type type) +{ + return stack_find_offset(stack_size(type)); +} + void SVMCompiler::stack_clear_offset(SocketType::Type type, int offset) { int size = stack_size(type); @@ -647,6 +651,9 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty case SHADER_TYPE_DISPLACEMENT: clin = node->input("Displacement"); break; + case SHADER_TYPE_BUMP: + clin = node->input("Normal"); + break; default: assert(0); break; @@ -663,6 +670,13 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty output->stack_offset = SVM_STACK_INVALID; } + /* for the bump shader we need add a node to store the shader state */ + int bump_state_offset = SVM_STACK_INVALID; + if(type == SHADER_TYPE_BUMP) { + bump_state_offset = stack_find_offset(SVM_BUMP_EVAL_STATE_SIZE); + add_node(NODE_ENTER_BUMP_EVAL, bump_state_offset); + } + if(shader->used) { if(clin->link) { bool generate = false; @@ -680,6 +694,9 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty generate = true; shader->has_displacement = true; break; + case SHADER_TYPE_BUMP: /* generate bump shader */ + generate = true; + break; default: break; } @@ -696,13 +713,21 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty node->compile(*this); } + /* add node to restore state after bump shader has finished */ + if(type == SHADER_TYPE_BUMP) { + add_node(NODE_LEAVE_BUMP_EVAL, bump_state_offset); + } + /* if compile failed, generate empty shader */ if(compile_failed) { svm_nodes.clear(); compile_failed = false; } - add_node(NODE_END, 0, 0, 0); + /* for bump shaders we fall thru to the surface shader, but if this is any other kind of shader it ends here */ + if(type != SHADER_TYPE_BUMP) { + add_node(NODE_END, 0, 0, 0); + } } void SVMCompiler::compile(Scene *scene, @@ -752,17 +777,22 @@ void SVMCompiler::compile(Scene *scene, shader->has_object_dependency = false; shader->has_integrator_dependency = false; - /* generate surface shader */ - if(shader->displacement_method == DISPLACE_TRUE || !shader->graph_bump) { - scoped_timer timer((summary != NULL)? &summary->time_generate_surface: NULL); - compile_type(shader, shader->graph, SHADER_TYPE_SURFACE); + /* generate bump shader */ + if(shader->displacement_method != DISPLACE_TRUE && shader->graph_bump) { + scoped_timer timer((summary != NULL)? &summary->time_generate_bump: NULL); + compile_type(shader, shader->graph_bump, SHADER_TYPE_BUMP); global_svm_nodes[index].y = global_svm_nodes.size(); global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end()); } - else { - scoped_timer timer((summary != NULL)? &summary->time_generate_bump: NULL); - compile_type(shader, shader->graph_bump, SHADER_TYPE_SURFACE); - global_svm_nodes[index].y = global_svm_nodes.size(); + + /* generate surface shader */ + { + scoped_timer timer((summary != NULL)? &summary->time_generate_surface: NULL); + compile_type(shader, shader->graph, SHADER_TYPE_SURFACE); + /* only set jump offset if there's no bump shader, as the bump shader will fall thru to this one if it exists */ + if(shader->displacement_method == DISPLACE_TRUE || !shader->graph_bump) { + global_svm_nodes[index].y = global_svm_nodes.size(); + } global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end()); } diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h index e14d57d7601..99e91ca0c3e 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -99,6 +99,7 @@ public: int stack_assign(ShaderInput *input); int stack_assign_if_linked(ShaderInput *input); int stack_assign_if_linked(ShaderOutput *output); + int stack_find_offset(int size); int stack_find_offset(SocketType::Type type); void stack_clear_offset(SocketType::Type type, int offset); void stack_link(ShaderInput *input, ShaderOutput *output); |