diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 023b5db7839..af57470aa89 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -116,7 +116,7 @@ ShaderOutput *ShaderNode::add_output(const char *name, ShaderSocketType type) return output; } -void ShaderNode::attributes(AttributeRequestSet *attributes) +void ShaderNode::attributes(Shader *shader, AttributeRequestSet *attributes) { foreach(ShaderInput *input, inputs) { if(!input->link) { @@ -151,9 +151,9 @@ ShaderNode *ShaderGraph::add(ShaderNode *node) return node; } -ShaderNode *ShaderGraph::output() +OutputNode *ShaderGraph::output() { - return nodes.front(); + return (OutputNode*)nodes.front(); } ShaderGraph *ShaderGraph::copy() diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index dfa737115e2..f31e2103229 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -29,12 +29,14 @@ CCL_NAMESPACE_BEGIN class AttributeRequestSet; +class Shader; class ShaderInput; class ShaderOutput; class ShaderNode; class ShaderGraph; class SVMCompiler; class OSLCompiler; +class OutputNode; /* Socket Type * @@ -182,7 +184,7 @@ public: ShaderOutput *add_output(const char *name, ShaderSocketType type); virtual ShaderNode *clone() const = 0; - virtual void attributes(AttributeRequestSet *attributes); + virtual void attributes(Shader *shader, AttributeRequestSet *attributes); virtual void compile(SVMCompiler& compiler) = 0; virtual void compile(OSLCompiler& compiler) = 0; @@ -238,7 +240,7 @@ public: ShaderGraph *copy(); ShaderNode *add(ShaderNode *node); - ShaderNode *output(); + OutputNode *output(); void connect(ShaderOutput *from, ShaderInput *to); void disconnect(ShaderInput *to); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index d7988656952..c6c050cd718 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -217,19 +217,19 @@ ShaderNode *ImageTextureNode::clone() const return node; } -void ImageTextureNode::attributes(AttributeRequestSet *attributes) +void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) { #ifdef WITH_PTEX /* todo: avoid loading other texture coordinates when using ptex, * and hide texture coordinate socket in the UI */ - if (string_endswith(filename, ".ptx")) { + if (shader->has_surface && string_endswith(filename, ".ptx")) { /* ptex */ attributes->add(ATTR_STD_PTEX_FACE_ID); attributes->add(ATTR_STD_PTEX_UV); } #endif - ShaderNode::attributes(attributes); + ShaderNode::attributes(shader, attributes); } void ImageTextureNode::compile(SVMCompiler& compiler) @@ -367,17 +367,17 @@ ShaderNode *EnvironmentTextureNode::clone() const return node; } -void EnvironmentTextureNode::attributes(AttributeRequestSet *attributes) +void EnvironmentTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) { #ifdef WITH_PTEX - if (string_endswith(filename, ".ptx")) { + if (shader->has_surface && string_endswith(filename, ".ptx")) { /* ptex */ attributes->add(ATTR_STD_PTEX_FACE_ID); attributes->add(ATTR_STD_PTEX_UV); } #endif - ShaderNode::attributes(attributes); + ShaderNode::attributes(shader, attributes); } void EnvironmentTextureNode::compile(SVMCompiler& compiler) @@ -1533,14 +1533,16 @@ WardBsdfNode::WardBsdfNode() add_input("Rotation", SHADER_SOCKET_FLOAT, 0.0f); } -void WardBsdfNode::attributes(AttributeRequestSet *attributes) +void WardBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) { - ShaderInput *tangent_in = input("Tangent"); + if(shader->has_surface) { + ShaderInput *tangent_in = input("Tangent"); - if(!tangent_in->link) - attributes->add(ATTR_STD_GENERATED); + if(!tangent_in->link) + attributes->add(ATTR_STD_GENERATED); + } - ShaderNode::attributes(attributes); + ShaderNode::attributes(shader, attributes); } void WardBsdfNode::compile(SVMCompiler& compiler) @@ -2088,12 +2090,14 @@ GeometryNode::GeometryNode() add_output("Backfacing", SHADER_SOCKET_FLOAT); } -void GeometryNode::attributes(AttributeRequestSet *attributes) +void GeometryNode::attributes(Shader *shader, AttributeRequestSet *attributes) { - if(!output("Tangent")->links.empty()) - attributes->add(ATTR_STD_GENERATED); + if(shader->has_surface) { + if(!output("Tangent")->links.empty()) + attributes->add(ATTR_STD_GENERATED); + } - ShaderNode::attributes(attributes); + ShaderNode::attributes(shader, attributes); } void GeometryNode::compile(SVMCompiler& compiler) @@ -2178,16 +2182,18 @@ TextureCoordinateNode::TextureCoordinateNode() from_dupli = false; } -void TextureCoordinateNode::attributes(AttributeRequestSet *attributes) +void TextureCoordinateNode::attributes(Shader *shader, AttributeRequestSet *attributes) { - if(!from_dupli) { - if(!output("Generated")->links.empty()) - attributes->add(ATTR_STD_GENERATED); - if(!output("UV")->links.empty()) - attributes->add(ATTR_STD_UV); + if(shader->has_surface) { + if(!from_dupli) { + if(!output("Generated")->links.empty()) + attributes->add(ATTR_STD_GENERATED); + if(!output("UV")->links.empty()) + attributes->add(ATTR_STD_UV); + } } - ShaderNode::attributes(attributes); + ShaderNode::attributes(shader, attributes); } void TextureCoordinateNode::compile(SVMCompiler& compiler) @@ -2490,7 +2496,7 @@ ParticleInfoNode::ParticleInfoNode() add_output("Angular Velocity", SHADER_SOCKET_VECTOR); } -void ParticleInfoNode::attributes(AttributeRequestSet *attributes) +void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) { if(!output("Index")->links.empty()) attributes->add(ATTR_STD_PARTICLE); @@ -2511,7 +2517,7 @@ void ParticleInfoNode::attributes(AttributeRequestSet *attributes) if(!output("Angular Velocity")->links.empty()) attributes->add(ATTR_STD_PARTICLE); - ShaderNode::attributes(attributes); + ShaderNode::attributes(shader, attributes); } void ParticleInfoNode::compile(SVMCompiler& compiler) @@ -2588,14 +2594,16 @@ HairInfoNode::HairInfoNode() /*add_output("Fade", SHADER_SOCKET_FLOAT);*/ } -void HairInfoNode::attributes(AttributeRequestSet *attributes) +void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) { - ShaderOutput *intercept_out = output("Intercept"); + if(shader->has_surface) { + ShaderOutput *intercept_out = output("Intercept"); - if(!intercept_out->links.empty()) - attributes->add(ATTR_STD_CURVE_INTERCEPT); + if(!intercept_out->links.empty()) + attributes->add(ATTR_STD_CURVE_INTERCEPT); + } - ShaderNode::attributes(attributes); + ShaderNode::attributes(shader, attributes); } void HairInfoNode::compile(SVMCompiler& compiler) @@ -3106,16 +3114,18 @@ AttributeNode::AttributeNode() add_output("Fac", SHADER_SOCKET_FLOAT); } -void AttributeNode::attributes(AttributeRequestSet *attributes) +void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes) { - ShaderOutput *color_out = output("Color"); - ShaderOutput *vector_out = output("Vector"); - ShaderOutput *fac_out = output("Fac"); + if(shader->has_surface) { + ShaderOutput *color_out = output("Color"); + ShaderOutput *vector_out = output("Vector"); + ShaderOutput *fac_out = output("Fac"); - if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) - attributes->add(attribute); + if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) + attributes->add(attribute); + } - ShaderNode::attributes(attributes); + ShaderNode::attributes(shader, attributes); } void AttributeNode::compile(SVMCompiler& compiler) @@ -3831,9 +3841,9 @@ NormalMapNode::NormalMapNode() add_output("Normal", SHADER_SOCKET_NORMAL); } -void NormalMapNode::attributes(AttributeRequestSet *attributes) +void NormalMapNode::attributes(Shader *shader, AttributeRequestSet *attributes) { - if(space == ustring("Tangent")) { + if(shader->has_surface && space == ustring("Tangent")) { if(attribute == ustring("")) { attributes->add(ATTR_STD_UV_TANGENT); attributes->add(ATTR_STD_UV_TANGENT_SIGN); @@ -3846,7 +3856,7 @@ void NormalMapNode::attributes(AttributeRequestSet *attributes) attributes->add(ATTR_STD_VERTEX_NORMAL); } - ShaderNode::attributes(attributes); + ShaderNode::attributes(shader, attributes); } void NormalMapNode::compile(SVMCompiler& compiler) @@ -3935,18 +3945,20 @@ TangentNode::TangentNode() add_output("Tangent", SHADER_SOCKET_NORMAL); } -void TangentNode::attributes(AttributeRequestSet *attributes) +void TangentNode::attributes(Shader *shader, AttributeRequestSet *attributes) { - if(direction_type == ustring("UV Map")) { - if(attribute == ustring("")) - attributes->add(ATTR_STD_UV_TANGENT); + if(shader->has_surface) { + if(direction_type == ustring("UV Map")) { + if(attribute == ustring("")) + attributes->add(ATTR_STD_UV_TANGENT); + else + attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); + } else - attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); + attributes->add(ATTR_STD_GENERATED); } - else - attributes->add(ATTR_STD_GENERATED); - ShaderNode::attributes(attributes); + ShaderNode::attributes(shader, attributes); } void TangentNode::compile(SVMCompiler& compiler) diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 36348044bbc..86c4f490875 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -66,7 +66,7 @@ public: SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode) ~ImageTextureNode(); ShaderNode *clone() const; - void attributes(AttributeRequestSet *attributes); + void attributes(Shader *shader, AttributeRequestSet *attributes); ImageManager *image_manager; int slot; @@ -88,7 +88,7 @@ public: SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode) ~EnvironmentTextureNode(); ShaderNode *clone() const; - void attributes(AttributeRequestSet *attributes); + void attributes(Shader *shader, AttributeRequestSet *attributes); ImageManager *image_manager; int slot; @@ -217,7 +217,7 @@ public: class WardBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(WardBsdfNode) - void attributes(AttributeRequestSet *attributes); + void attributes(Shader *shader, AttributeRequestSet *attributes); }; class DiffuseBsdfNode : public BsdfNode { @@ -338,13 +338,13 @@ public: class GeometryNode : public ShaderNode { public: SHADER_NODE_CLASS(GeometryNode) - void attributes(AttributeRequestSet *attributes); + void attributes(Shader *shader, AttributeRequestSet *attributes); }; class TextureCoordinateNode : public ShaderNode { public: SHADER_NODE_CLASS(TextureCoordinateNode) - void attributes(AttributeRequestSet *attributes); + void attributes(Shader *shader, AttributeRequestSet *attributes); bool from_dupli; }; @@ -367,14 +367,14 @@ public: class ParticleInfoNode : public ShaderNode { public: SHADER_NODE_CLASS(ParticleInfoNode) - void attributes(AttributeRequestSet *attributes); + void attributes(Shader *shader, AttributeRequestSet *attributes); }; class HairInfoNode : public ShaderNode { public: SHADER_NODE_CLASS(HairInfoNode) - void attributes(AttributeRequestSet *attributes); + void attributes(Shader *shader, AttributeRequestSet *attributes); }; class ValueNode : public ShaderNode { @@ -459,7 +459,7 @@ public: class AttributeNode : public ShaderNode { public: SHADER_NODE_CLASS(AttributeNode) - void attributes(AttributeRequestSet *attributes); + void attributes(Shader *shader, AttributeRequestSet *attributes); ustring attribute; }; @@ -580,7 +580,7 @@ public: class NormalMapNode : public ShaderNode { public: SHADER_NODE_CLASS(NormalMapNode) - void attributes(AttributeRequestSet *attributes); + void attributes(Shader *shader, AttributeRequestSet *attributes); ustring space; static ShaderEnum space_enum; @@ -591,7 +591,7 @@ public: class TangentNode : public ShaderNode { public: SHADER_NODE_CLASS(TangentNode) - void attributes(AttributeRequestSet *attributes); + void attributes(Shader *shader, AttributeRequestSet *attributes); ustring direction_type; static ShaderEnum direction_type_enum; diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 043d8d138f6..e2798f438e2 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -21,6 +21,7 @@ #include "osl.h" #include "scene.h" #include "shader.h" +#include "nodes.h" #ifdef WITH_OSL diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index fea90318671..20f0fd7ed1e 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -93,15 +93,24 @@ void Shader::tag_update(Scene *scene) if(use_mis && has_surface_emission) scene->light_manager->need_update = true; + /* quick detection of which kind of shaders we have to avoid loading + * e.g. surface attributes when there is only a volume shader. this could + * be more fine grained but it's better than nothing */ + OutputNode *output = graph->output(); + has_surface = has_surface || output->input("Surface")->link; + has_volume = has_volume || output->input("Volume")->link; + has_displacement = has_displacement || output->input("Displacement")->link; + /* get requested attributes. this could be optimized by pruning unused * nodes here already, but that's the job of the shader manager currently, * and may not be so great for interactive rendering where you temporarily * disconnect a node */ + AttributeRequestSet prev_attributes = attributes; attributes.clear(); foreach(ShaderNode *node, graph->nodes) - node->attributes(&attributes); + node->attributes(this, &attributes); /* compare if the attributes changed, mesh manager will check * need_update_attributes, update the relevant meshes and clear it. */ diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 930c53d9572..e5140ea990b 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -18,6 +18,7 @@ #include "graph.h" #include "light.h" #include "mesh.h" +#include "nodes.h" #include "scene.h" #include "shader.h" #include "svm.h"