diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index f31e2103229..263ce59156a 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -193,6 +193,7 @@ public: virtual bool has_surface_bssrdf() { return false; } virtual bool has_converter_blackbody() { return false; } virtual bool has_bssrdf_bump() { return false; } + virtual bool has_spatial_varying() { return false; } vector inputs; vector outputs; diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 31caf9507eb..054ae0f613c 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -209,6 +209,7 @@ public: BsdfNode(bool scattering = false); SHADER_NODE_BASE_CLASS(BsdfNode); + bool has_spatial_varying() { return true; } void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL, ShaderInput *param4 = NULL); ClosureType closure; @@ -280,6 +281,7 @@ public: SHADER_NODE_CLASS(SubsurfaceScatteringNode) bool has_surface_bssrdf() { return true; } bool has_bssrdf_bump(); + bool has_spatial_varying() { return true; } static ShaderEnum falloff_enum; }; @@ -289,6 +291,7 @@ public: SHADER_NODE_CLASS(EmissionNode) bool has_surface_emission() { return true; } + bool has_spatial_varying() { return true; } bool total_power; }; @@ -306,6 +309,8 @@ public: class AmbientOcclusionNode : public ShaderNode { public: SHADER_NODE_CLASS(AmbientOcclusionNode) + + bool has_spatial_varying() { return true; } }; class VolumeNode : public ShaderNode { @@ -340,12 +345,14 @@ class GeometryNode : public ShaderNode { public: SHADER_NODE_CLASS(GeometryNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_spatial_varying() { return true; } }; class TextureCoordinateNode : public ShaderNode { public: SHADER_NODE_CLASS(TextureCoordinateNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_spatial_varying() { return true; } bool from_dupli; }; @@ -354,6 +361,7 @@ class UVMapNode : public ShaderNode { public: SHADER_NODE_CLASS(UVMapNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_spatial_varying() { return true; } ustring attribute; bool from_dupli; @@ -367,6 +375,7 @@ public: class LightFalloffNode : public ShaderNode { public: SHADER_NODE_CLASS(LightFalloffNode) + bool has_spatial_varying() { return true; } }; class ObjectInfoNode : public ShaderNode { @@ -385,6 +394,7 @@ public: SHADER_NODE_CLASS(HairInfoNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_spatial_varying() { return true; } }; class ValueNode : public ShaderNode { @@ -470,6 +480,7 @@ class AttributeNode : public ShaderNode { public: SHADER_NODE_CLASS(AttributeNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_spatial_varying() { return true; } ustring attribute; }; @@ -477,21 +488,25 @@ public: class CameraNode : public ShaderNode { public: SHADER_NODE_CLASS(CameraNode) + bool has_spatial_varying() { return true; } }; class FresnelNode : public ShaderNode { public: SHADER_NODE_CLASS(FresnelNode) + bool has_spatial_varying() { return true; } }; class LayerWeightNode : public ShaderNode { public: SHADER_NODE_CLASS(LayerWeightNode) + bool has_spatial_varying() { return true; } }; class WireframeNode : public ShaderNode { public: SHADER_NODE_CLASS(WireframeNode) + bool has_spatial_varying() { return true; } bool use_pixel_size; }; @@ -548,6 +563,8 @@ public: class BumpNode : public ShaderNode { public: SHADER_NODE_CLASS(BumpNode) + bool has_spatial_varying() { return true; } + bool invert; }; @@ -578,6 +595,10 @@ public: class OSLScriptNode : public ShaderNode { public: SHADER_NODE_CLASS(OSLScriptNode) + + /* ideally we could beter detect this, but we can't query this now */ + bool has_spatial_varying() { return true; } + string filepath; string bytecode_hash; @@ -591,6 +612,7 @@ class NormalMapNode : public ShaderNode { public: SHADER_NODE_CLASS(NormalMapNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_spatial_varying() { return true; } ustring space; static ShaderEnum space_enum; @@ -602,6 +624,7 @@ class TangentNode : public ShaderNode { public: SHADER_NODE_CLASS(TangentNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_spatial_varying() { return true; } ustring direction_type; static ShaderEnum direction_type_enum; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 20f0fd7ed1e..b25673b36c3 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -53,6 +53,7 @@ Shader::Shader() has_volume = false; has_displacement = false; has_bssrdf_bump = false; + has_heterogeneous_volume = false; used = false; @@ -249,7 +250,7 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc * the case with camera inside volumes too */ flag |= SD_HAS_TRANSPARENT_SHADOW; } - if(shader->heterogeneous_volume) + if(shader->heterogeneous_volume && shader->has_heterogeneous_volume) flag |= SD_HETEROGENEOUS_VOLUME; if(shader->has_bssrdf_bump) flag |= SD_HAS_BSSRDF_BUMP; diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 5f87050fe19..874e8face7a 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -77,6 +77,7 @@ public: bool has_surface_bssrdf; bool has_converter_blackbody; bool has_bssrdf_bump; + bool has_heterogeneous_volume; /* requested mesh attributes */ AttributeRequestSet attributes; diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 377da67b5a4..c004187a091 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -379,6 +379,18 @@ void SVMCompiler::find_dependencies(set& dependencies, const set& done) +{ + node->compile(*this); + stack_clear_users(node, done); + stack_clear_temporary(node); + + if(current_type == SHADER_TYPE_VOLUME) { + if(node->has_spatial_varying()) + current_shader->has_heterogeneous_volume = true; + } +} + void SVMCompiler::generate_svm_nodes(const set& nodes, set& done) { bool nodes_done; @@ -400,9 +412,7 @@ void SVMCompiler::generate_svm_nodes(const set& nodes, sethas_converter_blackbody()) current_shader->has_converter_blackbody = true; - node->compile(*this); - stack_clear_users(node, done); - stack_clear_temporary(node); + generate_node(node, done); done.insert(node); } else @@ -485,9 +495,7 @@ void SVMCompiler::generate_closure(ShaderNode *node, set& done) } /* compile closure itself */ - node->compile(*this); - stack_clear_users(node, done); - stack_clear_temporary(node); + generate_node(node, done); if(current_type == SHADER_TYPE_SURFACE) { if(node->has_surface_emission()) @@ -550,9 +558,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set& don mix_weight_offset = SVM_STACK_INVALID; /* compile closure itself */ - node->compile(*this); - stack_clear_users(node, done); - stack_clear_temporary(node); + generate_node(node, done); mix_weight_offset = SVM_STACK_INVALID; @@ -694,6 +700,7 @@ void SVMCompiler::compile(Shader *shader, vector& global_svm_nodes, int in shader->has_converter_blackbody = false; shader->has_volume = false; shader->has_displacement = false; + shader->has_heterogeneous_volume = 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 3d84a67e173..069ba5247a2 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -124,6 +124,7 @@ protected: /* single closure */ void find_dependencies(set& dependencies, const set& done, ShaderInput *input); + void generate_node(ShaderNode *node, set& done); void generate_svm_nodes(const set& nodes, set& done); void generate_closure(ShaderNode *node, set& done);