diff options
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/graph.cpp | 18 | ||||
-rw-r--r-- | intern/cycles/render/graph.h | 13 | ||||
-rw-r--r-- | intern/cycles/render/integrator.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 101 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 16 | ||||
-rw-r--r-- | intern/cycles/render/osl.cpp | 22 | ||||
-rw-r--r-- | intern/cycles/render/osl.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/shader.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/render/shader.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/svm.cpp | 25 | ||||
-rw-r--r-- | intern/cycles/render/svm.h | 5 |
11 files changed, 160 insertions, 53 deletions
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 749640040f5..7e6e960d585 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -266,7 +266,10 @@ void ShaderGraph::relink(vector<ShaderInput*> inputs, vector<ShaderInput*> outpu } } -void ShaderGraph::finalize(bool do_bump, bool do_osl) +void ShaderGraph::finalize(Scene *scene, + bool do_bump, + bool do_osl, + bool do_simplify) { /* before compiling, the shader graph may undergo a number of modifications. * currently we set default geometry shader inputs, and create automatic bump @@ -274,7 +277,7 @@ void ShaderGraph::finalize(bool do_bump, bool do_osl) * modified afterwards. */ if(!finalized) { - clean(); + clean(scene); default_inputs(do_osl); refine_bump_nodes(); @@ -293,6 +296,9 @@ void ShaderGraph::finalize(bool do_bump, bool do_osl) finalized = true; } + else if(do_simplify) { + simplify_nodes(scene); + } } void ShaderGraph::find_dependencies(set<ShaderNode*>& dependencies, ShaderInput *input) @@ -557,10 +563,10 @@ void ShaderGraph::remove_unneeded_nodes() } /* Step 3: Simplification.*/ -void ShaderGraph::simplify_nodes() +void ShaderGraph::simplify_nodes(Scene *scene) { foreach(ShaderNode *node, nodes) { - node->optimize(); + node->optimize(scene); } } @@ -588,7 +594,7 @@ void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<b on_stack[node->id] = false; } -void ShaderGraph::clean() +void ShaderGraph::clean(Scene *scene) { /* Graph simplification: * 1: Remove unnecesarry nodes @@ -604,7 +610,7 @@ void ShaderGraph::clean() /* TODO(dingto): Implement */ /* 3: Simplification. */ - simplify_nodes(); + simplify_nodes(scene); /* 4: De-duplication. */ /* TODO(dingto): Implement */ diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index fa2de3703c0..a2c210f4f60 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -29,6 +29,7 @@ CCL_NAMESPACE_BEGIN class AttributeRequestSet; +class Scene; class Shader; class ShaderInput; class ShaderOutput; @@ -196,7 +197,7 @@ public: virtual void attributes(Shader *shader, AttributeRequestSet *attributes); virtual void compile(SVMCompiler& compiler) = 0; virtual void compile(OSLCompiler& compiler) = 0; - virtual void optimize() {}; + virtual void optimize(Scene * /*scene*/) {}; virtual bool has_surface_emission() { return false; } virtual bool has_surface_transparent() { return false; } @@ -204,6 +205,7 @@ public: virtual bool has_bssrdf_bump() { return false; } virtual bool has_spatial_varying() { return false; } virtual bool has_object_dependency() { return false; } + virtual bool has_integrator_dependency() { return false; } vector<ShaderInput*> inputs; vector<ShaderOutput*> outputs; @@ -276,8 +278,10 @@ public: void relink(vector<ShaderInput*> inputs, vector<ShaderInput*> outputs, ShaderOutput *output); void remove_unneeded_nodes(); - void simplify_nodes(); - void finalize(bool do_bump = false, bool do_osl = false); + void finalize(Scene *scene, + bool do_bump = false, + bool do_osl = false, + bool do_simplify = false); int get_num_closures(); @@ -290,7 +294,8 @@ protected: void copy_nodes(set<ShaderNode*>& nodes, map<ShaderNode*, ShaderNode*>& nnodemap); void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack); - void clean(); + void clean(Scene *scene); + void simplify_nodes(Scene *scene); void bump_from_displacement(); void refine_bump_nodes(); void default_inputs(bool do_osl); diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index 9f8d5b50ccd..47489f6e007 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -18,6 +18,7 @@ #include "integrator.h" #include "light.h" #include "scene.h" +#include "shader.h" #include "sobol.h" #include "util_foreach.h" @@ -217,8 +218,14 @@ bool Integrator::modified(const Integrator& integrator) sample_all_lights_indirect == integrator.sample_all_lights_indirect); } -void Integrator::tag_update(Scene * /*scene*/) +void Integrator::tag_update(Scene *scene) { + foreach(Shader *shader, scene->shaders) { + if(shader->has_integrator_dependency) { + scene->shader_manager->need_update = true; + break; + } + } need_update = true; } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index d8d88b4851e..d89e74837c7 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -15,7 +15,9 @@ */ #include "image.h" +#include "integrator.h" #include "nodes.h" +#include "scene.h" #include "svm.h" #include "svm_math_util.h" #include "osl.h" @@ -1874,20 +1876,37 @@ GlossyBsdfNode::GlossyBsdfNode() { closure = CLOSURE_BSDF_MICROFACET_GGX_ID; distribution = ustring("GGX"); + distribution_orig = ustring(""); add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f); } -void GlossyBsdfNode::optimize() +void GlossyBsdfNode::optimize(Scene *scene) { - /* Fallback to Sharp closure for Roughness close to 0. - * Note: Keep the epsilon in sync with kernel! - */ - ShaderInput *roughness_input = get_input("Roughness"); - if(!roughness_input->link && roughness_input->value.x <= 1e-4f) { - closure = CLOSURE_BSDF_REFLECTION_ID; - distribution = ustring("Sharp"); + if(distribution_orig == "") { + distribution_orig = distribution; + } + Integrator *integrator = scene->integrator; + if(integrator->filter_glossy == 0.0f) { + /* Fallback to Sharp closure for Roughness close to 0. + * Note: Keep the epsilon in sync with kernel! + */ + ShaderInput *roughness_input = get_input("Roughness"); + if(!roughness_input->link && roughness_input->value.x <= 1e-4f) { + distribution = ustring("Sharp"); + } } + else { + /* Rollback to original distribution when filter glossy is used. */ + distribution = distribution_orig; + } + closure = (ClosureType)distribution_enum[distribution]; +} + +bool GlossyBsdfNode::has_integrator_dependency() +{ + ShaderInput *roughness_input = get_input("Roughness"); + return !roughness_input->link && roughness_input->value.x <= 1e-4f; } void GlossyBsdfNode::compile(SVMCompiler& compiler) @@ -1925,21 +1944,38 @@ GlassBsdfNode::GlassBsdfNode() { closure = CLOSURE_BSDF_SHARP_GLASS_ID; distribution = ustring("Sharp"); + distribution_orig = ustring(""); add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f); add_input("IOR", SHADER_SOCKET_FLOAT, 0.3f); } -void GlassBsdfNode::optimize() +void GlassBsdfNode::optimize(Scene *scene) { - /* Fallback to Sharp closure for Roughness close to 0. - * Note: Keep the epsilon in sync with kernel! - */ - ShaderInput *roughness_input = get_input("Roughness"); - if(!roughness_input->link && roughness_input->value.x <= 1e-4f) { - closure = CLOSURE_BSDF_SHARP_GLASS_ID; - distribution = ustring("Sharp"); + if(distribution_orig == "") { + distribution_orig = distribution; + } + Integrator *integrator = scene->integrator; + if(integrator->filter_glossy == 0.0f) { + /* Fallback to Sharp closure for Roughness close to 0. + * Note: Keep the epsilon in sync with kernel! + */ + ShaderInput *roughness_input = get_input("Roughness"); + if(!roughness_input->link && roughness_input->value.x <= 1e-4f) { + distribution = ustring("Sharp"); + } + } + else { + /* Rollback to original distribution when filter glossy is used. */ + distribution = distribution_orig; } + closure = (ClosureType)distribution_enum[distribution]; +} + +bool GlassBsdfNode::has_integrator_dependency() +{ + ShaderInput *roughness_input = get_input("Roughness"); + return !roughness_input->link && roughness_input->value.x <= 1e-4f; } void GlassBsdfNode::compile(SVMCompiler& compiler) @@ -1977,21 +2013,38 @@ RefractionBsdfNode::RefractionBsdfNode() { closure = CLOSURE_BSDF_REFRACTION_ID; distribution = ustring("Sharp"); + distribution_orig = ustring(""); add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f); add_input("IOR", SHADER_SOCKET_FLOAT, 0.3f); } -void RefractionBsdfNode::optimize() +void RefractionBsdfNode::optimize(Scene *scene) { - /* Fallback to Sharp closure for Roughness close to 0. - * Note: Keep the epsilon in sync with kernel! - */ - ShaderInput *roughness_input = get_input("Roughness"); - if(!roughness_input->link && roughness_input->value.x <= 1e-4f) { - closure = CLOSURE_BSDF_REFRACTION_ID; - distribution = ustring("Sharp"); + if(distribution_orig == "") { + distribution_orig = distribution; + } + Integrator *integrator = scene->integrator; + if(integrator->filter_glossy == 0.0f) { + /* Fallback to Sharp closure for Roughness close to 0. + * Note: Keep the epsilon in sync with kernel! + */ + ShaderInput *roughness_input = get_input("Roughness"); + if(!roughness_input->link && roughness_input->value.x <= 1e-4f) { + distribution = ustring("Sharp"); + } } + else { + /* Rollback to original distribution when filter glossy is used. */ + distribution = distribution_orig; + } + closure = (ClosureType)distribution_enum[distribution]; +} + +bool RefractionBsdfNode::has_integrator_dependency() +{ + ShaderInput *roughness_input = get_input("Roughness"); + return !roughness_input->link && roughness_input->value.x <= 1e-4f; } void RefractionBsdfNode::compile(SVMCompiler& compiler) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 2b205c44d42..4f4061286cb 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -24,6 +24,7 @@ CCL_NAMESPACE_BEGIN class ImageManager; +class Scene; class Shader; /* Texture Mapping */ @@ -310,9 +311,10 @@ class GlossyBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(GlossyBsdfNode) - void optimize(); + void optimize(Scene *scene); + bool has_integrator_dependency(); - ustring distribution; + ustring distribution, distribution_orig; static ShaderEnum distribution_enum; }; @@ -320,9 +322,10 @@ class GlassBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(GlassBsdfNode) - void optimize(); + void optimize(Scene *scene); + bool has_integrator_dependency(); - ustring distribution; + ustring distribution, distribution_orig; static ShaderEnum distribution_enum; }; @@ -330,9 +333,10 @@ class RefractionBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(RefractionBsdfNode) - void optimize(); + void optimize(Scene *scene); + bool has_integrator_dependency(); - ustring distribution; + ustring distribution, distribution_orig; static ShaderEnum distribution_enum; }; diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index a02f91ad2cf..c73deb15edd 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -100,7 +100,7 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene OSLCompiler compiler((void*)this, (void*)ss, scene->image_manager); compiler.background = (shader == scene->shaders[scene->default_background]); - compiler.compile(og, shader); + compiler.compile(scene, og, shader); if(shader->use_mis && shader->has_surface_emission) scene->light_manager->need_update = true; @@ -573,6 +573,10 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) if(node->has_object_dependency()) { current_shader->has_object_dependency = true; } + + if(node->has_integrator_dependency()) { + current_shader->has_integrator_dependency = true; + } } void OSLCompiler::parameter(const char *name, float f) @@ -788,7 +792,7 @@ OSL::ShadingAttribStateRef OSLCompiler::compile_type(Shader *shader, ShaderGraph return group; } -void OSLCompiler::compile(OSLGlobals *og, Shader *shader) +void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader) { if(shader->need_update) { ShaderGraph *graph = shader->graph; @@ -800,9 +804,16 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader) shader->graph_bump = shader->graph->copy(); /* finalize */ - shader->graph->finalize(false, true); - if(shader->graph_bump) - shader->graph_bump->finalize(true, true); + shader->graph->finalize(scene, + false, + true, + shader->has_integrator_dependency); + if(shader->graph_bump) { + shader->graph_bump->finalize(scene, + true, + true, + shader->has_integrator_dependency); + } current_shader = shader; @@ -815,6 +826,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader) shader->has_displacement = false; shader->has_heterogeneous_volume = false; shader->has_object_dependency = false; + shader->has_integrator_dependency = false; /* generate surface shader */ if(shader->used && graph && output->input("Surface")->link) { diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h index bc6a9d8fbbd..e915f830202 100644 --- a/intern/cycles/render/osl.h +++ b/intern/cycles/render/osl.h @@ -113,7 +113,7 @@ protected: class OSLCompiler { public: OSLCompiler(void *manager, void *shadingsys, ImageManager *image_manager); - void compile(OSLGlobals *og, Shader *shader); + void compile(Scene *scene, OSLGlobals *og, Shader *shader); void add(ShaderNode *node, const char *name, bool isfilepath = false); diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index aba3e7237d2..ae00bfb30a7 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -154,6 +154,7 @@ Shader::Shader() has_bssrdf_bump = false; has_heterogeneous_volume = false; has_object_dependency = false; + has_integrator_dependency = false; used = false; diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 64d45635ef1..e34e78476a0 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -107,6 +107,7 @@ public: bool has_bssrdf_bump; bool has_heterogeneous_volume; bool has_object_dependency; + bool has_integrator_dependency; /* requested mesh attributes */ AttributeRequestSet attributes; diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index e81b2f3a827..ad0ef959d22 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -78,7 +78,7 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene SVMCompiler compiler(scene->shader_manager, scene->image_manager); compiler.background = ((int)i == scene->default_background); - compiler.compile(shader, svm_nodes, i); + compiler.compile(scene, shader, svm_nodes, i); } dscene->svm_nodes.copy((uint4*)&svm_nodes[0], svm_nodes.size()); @@ -396,6 +396,10 @@ void SVMCompiler::generate_node(ShaderNode *node, set<ShaderNode*>& done) if(node->has_object_dependency()) { current_shader->has_object_dependency = true; } + + if(node->has_integrator_dependency()) { + current_shader->has_integrator_dependency = true; + } } void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done) @@ -691,7 +695,10 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty add_node(NODE_END, 0, 0, 0); } -void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int index) +void SVMCompiler::compile(Scene *scene, + Shader *shader, + vector<int4>& global_svm_nodes, + int index) { /* copy graph for shader with bump mapping */ ShaderNode *node = shader->graph->output(); @@ -701,9 +708,16 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in shader->graph_bump = shader->graph->copy(); /* finalize */ - shader->graph->finalize(false, false); - if(shader->graph_bump) - shader->graph_bump->finalize(true, false); + shader->graph->finalize(scene, + false, + false, + shader->has_integrator_dependency); + if(shader->graph_bump) { + shader->graph_bump->finalize(scene, + true, + false, + shader->has_integrator_dependency); + } current_shader = shader; @@ -716,6 +730,7 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in shader->has_displacement = false; shader->has_heterogeneous_volume = false; shader->has_object_dependency = false; + shader->has_integrator_dependency = false; /* generate surface shader */ compile_type(shader, shader->graph, SHADER_TYPE_SURFACE); diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h index 4b390fb88f9..e48fe5e32ed 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -53,7 +53,10 @@ public: class SVMCompiler { public: SVMCompiler(ShaderManager *shader_manager, ImageManager *image_manager); - void compile(Shader *shader, vector<int4>& svm_nodes, int index); + void compile(Scene *scene, + Shader *shader, + vector<int4>& svm_nodes, + int index); void stack_assign(ShaderOutput *output); void stack_assign(ShaderInput *input); |