From a963c7d48dade70474ec3b40bea5e99ebdbbc5d4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 18 Feb 2018 03:20:39 +0100 Subject: Code refactor: improve attribute handling for optional volume attributes. A volume shader should be able to request attributes, and still be rendered as homogeneous if no volume attributes are available for the object. --- intern/cycles/kernel/kernel_types.h | 12 ++++++--- intern/cycles/kernel/kernel_volume.h | 15 ++++++++++- intern/cycles/render/attribute.cpp | 32 ++++++++++++++++++---- intern/cycles/render/attribute.h | 1 + intern/cycles/render/graph.h | 1 + intern/cycles/render/nodes.cpp | 52 +++++++++++++++--------------------- intern/cycles/render/nodes.h | 14 ++++++++++ intern/cycles/render/object.cpp | 9 ++++++- intern/cycles/render/osl.cpp | 13 +++++++++ intern/cycles/render/osl.h | 2 ++ intern/cycles/render/shader.cpp | 3 +++ intern/cycles/render/shader.h | 1 + intern/cycles/render/svm.cpp | 11 ++++++++ intern/cycles/render/svm.h | 1 + 14 files changed, 126 insertions(+), 41 deletions(-) (limited to 'intern') diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 26b5a27807c..d967edca75d 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -925,19 +925,22 @@ enum ShaderDataFlag { SD_HAS_DISPLACEMENT = (1 << 26), /* Has constant emission (value stored in __shader_flag) */ SD_HAS_CONSTANT_EMISSION = (1 << 27), + /* Needs to access attributes */ + SD_NEED_ATTRIBUTES = (1 << 28), SD_SHADER_FLAGS = (SD_USE_MIS | SD_HAS_TRANSPARENT_SHADOW | SD_HAS_VOLUME | SD_HAS_ONLY_VOLUME | - SD_HETEROGENEOUS_VOLUME| + SD_HETEROGENEOUS_VOLUME | SD_HAS_BSSRDF_BUMP | SD_VOLUME_EQUIANGULAR | SD_VOLUME_MIS | SD_VOLUME_CUBIC | SD_HAS_BUMP | SD_HAS_DISPLACEMENT | - SD_HAS_CONSTANT_EMISSION) + SD_HAS_CONSTANT_EMISSION | + SD_NEED_ATTRIBUTES) }; /* Object flags. */ @@ -958,6 +961,8 @@ enum ShaderDataObjectFlag { SD_OBJECT_HAS_VERTEX_MOTION = (1 << 6), /* object is used to catch shadows */ SD_OBJECT_SHADOW_CATCHER = (1 << 7), + /* object has volume attributes */ + SD_OBJECT_HAS_VOLUME_ATTRIBUTES = (1 << 8), SD_OBJECT_FLAGS = (SD_OBJECT_HOLDOUT_MASK | SD_OBJECT_MOTION | @@ -965,7 +970,8 @@ enum ShaderDataObjectFlag { SD_OBJECT_NEGATIVE_SCALE_APPLIED | SD_OBJECT_HAS_VOLUME | SD_OBJECT_INTERSECTS_VOLUME | - SD_OBJECT_SHADOW_CATCHER) + SD_OBJECT_SHADOW_CATCHER | + SD_OBJECT_HAS_VOLUME_ATTRIBUTES) }; typedef ccl_addr_space struct ShaderData { diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h index 3274e05f98e..058e7dccafd 100644 --- a/intern/cycles/kernel/kernel_volume.h +++ b/intern/cycles/kernel/kernel_volume.h @@ -106,8 +106,21 @@ ccl_device bool volume_stack_is_heterogeneous(KernelGlobals *kg, ccl_addr_space for(int i = 0; stack[i].shader != SHADER_NONE; i++) { int shader_flag = kernel_tex_fetch(__shader_flag, (stack[i].shader & SHADER_MASK)*SHADER_SIZE); - if(shader_flag & SD_HETEROGENEOUS_VOLUME) + if(shader_flag & SD_HETEROGENEOUS_VOLUME) { return true; + } + else if(shader_flag & SD_NEED_ATTRIBUTES) { + /* We want to render world or objects without any volume grids + * as homogenous, but can only verify this at runtime since other + * heterogenous volume objects may be using the same shader. */ + int object = stack[i].object; + if(object != OBJECT_NONE) { + int object_flag = kernel_tex_fetch(__object_flag, object); + if(object_flag & SD_OBJECT_HAS_VOLUME_ATTRIBUTES) { + return true; + } + } + } } return false; diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index f959b1fef8b..6816f8ca3f3 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -298,9 +298,13 @@ const char *Attribute::standard_name(AttributeStandard std) AttributeStandard Attribute::name_standard(const char *name) { - for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++) - if(strcmp(name, Attribute::standard_name((AttributeStandard)std)) == 0) - return (AttributeStandard)std; + if(name) { + for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++) { + if(strcmp(name, Attribute::standard_name((AttributeStandard)std)) == 0) { + return (AttributeStandard)std; + } + } + } return ATTR_STD_NONE; } @@ -615,9 +619,11 @@ bool AttributeRequestSet::modified(const AttributeRequestSet& other) void AttributeRequestSet::add(ustring name) { - foreach(AttributeRequest& req, requests) - if(req.name == name) + foreach(AttributeRequest& req, requests) { + if(req.name == name) { return; + } + } requests.push_back(AttributeRequest(name)); } @@ -641,6 +647,22 @@ void AttributeRequestSet::add(AttributeRequestSet& reqs) } } +void AttributeRequestSet::add_standard(ustring name) +{ + if(!name) { + return; + } + + AttributeStandard std = Attribute::name_standard(name.c_str()); + + if(std) { + add(std); + } + else { + add(name); + } +} + bool AttributeRequestSet::find(ustring name) { foreach(AttributeRequest& req, requests) diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h index d15ee401a72..9e23345675d 100644 --- a/intern/cycles/render/attribute.h +++ b/intern/cycles/render/attribute.h @@ -159,6 +159,7 @@ public: void add(ustring name); void add(AttributeStandard std); void add(AttributeRequestSet& reqs); + void add_standard(ustring name); bool find(ustring name); bool find(AttributeStandard std); diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index 7ed292b5b96..2c134932b3c 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -156,6 +156,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_attribute_dependency() { return false; } virtual bool has_integrator_dependency() { return false; } virtual bool has_volume_support() { return false; } virtual bool has_raytrace() { return false; } diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 56c9e669a5c..60c536f1ec1 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -208,7 +208,7 @@ NODE_DEFINE(ImageTextureNode) TEXTURE_MAPPING_DEFINE(ImageTextureNode); - SOCKET_STRING(filename, "Filename", ustring("")); + SOCKET_STRING(filename, "Filename", ustring()); static NodeEnum color_space_enum; color_space_enum.insert("none", NODE_COLOR_SPACE_NONE); @@ -419,7 +419,7 @@ NODE_DEFINE(EnvironmentTextureNode) TEXTURE_MAPPING_DEFINE(EnvironmentTextureNode); - SOCKET_STRING(filename, "Filename", ustring("")); + SOCKET_STRING(filename, "Filename", ustring()); static NodeEnum color_space_enum; color_space_enum.insert("none", NODE_COLOR_SPACE_NONE); @@ -1348,7 +1348,7 @@ NODE_DEFINE(PointDensityTextureNode) { NodeType* type = NodeType::add("point_density_texture", create, NodeType::SHADER); - SOCKET_STRING(filename, "Filename", ustring("")); + SOCKET_STRING(filename, "Filename", ustring()); static NodeEnum space_enum; space_enum.insert("object", NODE_TEX_VOXEL_SPACE_OBJECT); @@ -3167,7 +3167,7 @@ NODE_DEFINE(UVMapNode) { NodeType* type = NodeType::add("uvmap", create, NodeType::SHADER); - SOCKET_IN_STRING(attribute, "attribute", ustring("")); + SOCKET_STRING(attribute, "attribute", ustring()); SOCKET_IN_BOOLEAN(from_dupli, "from dupli", false); SOCKET_OUT_POINT(UV, "UV"); @@ -4465,7 +4465,7 @@ NODE_DEFINE(AttributeNode) { NodeType* type = NodeType::add("attribute", create, NodeType::SHADER); - SOCKET_STRING(attribute, "Attribute", ustring("")); + SOCKET_STRING(attribute, "Attribute", ustring()); SOCKET_OUT_COLOR(color, "Color"); SOCKET_OUT_VECTOR(vector, "Vector"); @@ -4486,16 +4486,12 @@ void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes) ShaderOutput *fac_out = output("Fac"); if(!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) { - AttributeStandard std = Attribute::name_standard(attribute.c_str()); - - if(std != ATTR_STD_NONE) - attributes->add(std); - else - attributes->add(attribute); + attributes->add_standard(attribute); } - if(shader->has_volume) + if(shader->has_volume) { attributes->add(ATTR_STD_GENERATED_TRANSFORM); + } ShaderNode::attributes(shader, attributes); } @@ -4506,13 +4502,7 @@ void AttributeNode::compile(SVMCompiler& compiler) ShaderOutput *vector_out = output("Vector"); ShaderOutput *fac_out = output("Fac"); ShaderNodeType attr_node = NODE_ATTR; - AttributeStandard std = Attribute::name_standard(attribute.c_str()); - int attr; - - if(std != ATTR_STD_NONE) - attr = compiler.attribute(std); - else - attr = compiler.attribute(attribute); + int attr = compiler.attribute_standard(attribute);; if(bump == SHADER_BUMP_DX) attr_node = NODE_ATTR_BUMP_DX; @@ -5470,7 +5460,7 @@ NODE_DEFINE(NormalMapNode) space_enum.insert("blender_world", NODE_NORMAL_MAP_BLENDER_WORLD); SOCKET_ENUM(space, "Space", space_enum, NODE_TANGENT_RADIAL); - SOCKET_STRING(attribute, "Attribute", ustring("")); + SOCKET_STRING(attribute, "Attribute", ustring()); SOCKET_IN_NORMAL(normal_osl, "NormalIn", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL); SOCKET_IN_FLOAT(strength, "Strength", 1.0f); @@ -5489,7 +5479,7 @@ NormalMapNode::NormalMapNode() void NormalMapNode::attributes(Shader *shader, AttributeRequestSet *attributes) { if(shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) { - if(attribute == ustring("")) { + if(attribute.empty()) { attributes->add(ATTR_STD_UV_TANGENT); attributes->add(ATTR_STD_UV_TANGENT_SIGN); } @@ -5512,7 +5502,7 @@ void NormalMapNode::compile(SVMCompiler& compiler) int attr = 0, attr_sign = 0; if(space == NODE_NORMAL_MAP_TANGENT) { - if(attribute == ustring("")) { + if(attribute.empty()) { attr = compiler.attribute(ATTR_STD_UV_TANGENT); attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN); } @@ -5534,7 +5524,7 @@ void NormalMapNode::compile(SVMCompiler& compiler) void NormalMapNode::compile(OSLCompiler& compiler) { if(space == NODE_NORMAL_MAP_TANGENT) { - if(attribute == ustring("")) { + if(attribute.empty()) { compiler.parameter("attr_name", ustring("geom:tangent")); compiler.parameter("attr_sign_name", ustring("geom:tangent_sign")); } @@ -5565,7 +5555,7 @@ NODE_DEFINE(TangentNode) axis_enum.insert("z", NODE_TANGENT_AXIS_Z); SOCKET_ENUM(axis, "Axis", axis_enum, NODE_TANGENT_AXIS_X); - SOCKET_STRING(attribute, "Attribute", ustring("")); + SOCKET_STRING(attribute, "Attribute", ustring()); SOCKET_IN_NORMAL(normal_osl, "NormalIn", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL | SocketType::OSL_INTERNAL); SOCKET_OUT_NORMAL(tangent, "Tangent"); @@ -5582,7 +5572,7 @@ void TangentNode::attributes(Shader *shader, AttributeRequestSet *attributes) { if(shader->has_surface) { if(direction_type == NODE_TANGENT_UVMAP) { - if(attribute == ustring("")) + if(attribute.empty()) attributes->add(ATTR_STD_UV_TANGENT); else attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); @@ -5600,7 +5590,7 @@ void TangentNode::compile(SVMCompiler& compiler) int attr; if(direction_type == NODE_TANGENT_UVMAP) { - if(attribute == ustring("")) + if(attribute.empty()) attr = compiler.attribute(ATTR_STD_UV_TANGENT); else attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str())); @@ -5618,7 +5608,7 @@ void TangentNode::compile(SVMCompiler& compiler) void TangentNode::compile(OSLCompiler& compiler) { if(direction_type == NODE_TANGENT_UVMAP) { - if(attribute == ustring("")) + if(attribute.empty()) compiler.parameter("attr_name", ustring("geom:tangent")); else compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str())); @@ -5731,7 +5721,7 @@ NODE_DEFINE(VectorDisplacementNode) space_enum.insert("world", NODE_NORMAL_MAP_WORLD); SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT); - SOCKET_STRING(attribute, "Attribute", ustring("")); + SOCKET_STRING(attribute, "Attribute", ustring()); SOCKET_IN_COLOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.0f); @@ -5750,7 +5740,7 @@ VectorDisplacementNode::VectorDisplacementNode() void VectorDisplacementNode::attributes(Shader *shader, AttributeRequestSet *attributes) { if(shader->has_surface && space == NODE_NORMAL_MAP_TANGENT) { - if(attribute == ustring("")) { + if(attribute.empty()) { attributes->add(ATTR_STD_UV_TANGENT); attributes->add(ATTR_STD_UV_TANGENT_SIGN); } @@ -5774,7 +5764,7 @@ void VectorDisplacementNode::compile(SVMCompiler& compiler) int attr = 0, attr_sign = 0; if(space == NODE_NORMAL_MAP_TANGENT) { - if(attribute == ustring("")) { + if(attribute.empty()) { attr = compiler.attribute(ATTR_STD_UV_TANGENT); attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN); } @@ -5797,7 +5787,7 @@ void VectorDisplacementNode::compile(SVMCompiler& compiler) void VectorDisplacementNode::compile(OSLCompiler& compiler) { if(space == NODE_NORMAL_MAP_TANGENT) { - if(attribute == ustring("")) { + if(attribute.empty()) { compiler.parameter("attr_name", ustring("geom:tangent")); compiler.parameter("attr_sign_name", ustring("geom:tangent_sign")); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index f664ebf545d..bc516af4511 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -82,6 +82,7 @@ public: ~ImageTextureNode(); ShaderNode *clone() const; void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } ImageManager *image_manager; int is_float; @@ -112,6 +113,7 @@ public: ~EnvironmentTextureNode(); ShaderNode *clone() const; void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } virtual int get_group() { return NODE_GROUP_LEVEL_2; } ImageManager *image_manager; @@ -257,6 +259,7 @@ public: ~PointDensityTextureNode(); ShaderNode *clone() const; void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } bool has_spatial_varying() { return true; } bool has_object_dependency() { return true; } @@ -361,6 +364,7 @@ public: ClosureType get_closure_type() { return distribution; } void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } }; class DiffuseBsdfNode : public BsdfNode { @@ -394,6 +398,7 @@ public: bool has_integrator_dependency(); void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } }; class TranslucentBsdfNode : public BsdfNode { @@ -572,6 +577,7 @@ class GeometryNode : public ShaderNode { public: SHADER_NODE_CLASS(GeometryNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } bool has_spatial_varying() { return true; } float3 normal_osl; @@ -581,6 +587,7 @@ class TextureCoordinateNode : public ShaderNode { public: SHADER_NODE_CLASS(TextureCoordinateNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } bool has_spatial_varying() { return true; } bool has_object_dependency() { return use_transform; } @@ -594,6 +601,7 @@ class UVMapNode : public ShaderNode { public: SHADER_NODE_CLASS(UVMapNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } bool has_spatial_varying() { return true; } virtual int get_group() { return NODE_GROUP_LEVEL_1; } @@ -627,6 +635,7 @@ class ParticleInfoNode : public ShaderNode { public: SHADER_NODE_CLASS(ParticleInfoNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } virtual int get_group() { return NODE_GROUP_LEVEL_1; } }; @@ -635,6 +644,7 @@ public: SHADER_NODE_CLASS(HairInfoNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } bool has_spatial_varying() { return true; } virtual int get_group() { return NODE_GROUP_LEVEL_1; } virtual int get_feature() { @@ -796,6 +806,7 @@ class AttributeNode : public ShaderNode { public: SHADER_NODE_CLASS(AttributeNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } bool has_spatial_varying() { return true; } ustring attribute; @@ -993,6 +1004,7 @@ class NormalMapNode : public ShaderNode { public: SHADER_NODE_CLASS(NormalMapNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } bool has_spatial_varying() { return true; } virtual int get_group() { return NODE_GROUP_LEVEL_3; } @@ -1007,6 +1019,7 @@ class TangentNode : public ShaderNode { public: SHADER_NODE_CLASS(TangentNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } bool has_spatial_varying() { return true; } virtual int get_group() { return NODE_GROUP_LEVEL_3; } @@ -1046,6 +1059,7 @@ class VectorDisplacementNode : public ShaderNode { public: SHADER_NODE_CLASS(VectorDisplacementNode) void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() { return true; } virtual int get_feature() { return NODE_FEATURE_BUMP; } diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index e03160954bc..b981d2b8849 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -604,9 +604,16 @@ void ObjectManager::device_update_flags(Device *, foreach(Object *object, scene->objects) { if(object->mesh->has_volume) { object_flag[object_index] |= SD_OBJECT_HAS_VOLUME; + object_flag[object_index] &= ~SD_OBJECT_HAS_VOLUME_ATTRIBUTES; + + foreach(Attribute& attr, object->mesh->attributes.attributes) { + if(attr.element == ATTR_ELEMENT_VOXEL) { + object_flag[object_index] |= SD_OBJECT_HAS_VOLUME_ATTRIBUTES; + } + } } else { - object_flag[object_index] &= ~SD_OBJECT_HAS_VOLUME; + object_flag[object_index] &= ~(SD_OBJECT_HAS_VOLUME|SD_OBJECT_HAS_VOLUME_ATTRIBUTES); } if(object->is_shadow_catcher) { object_flag[object_index] |= SD_OBJECT_SHADOW_CATCHER; diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 4d066c89b76..9e931280691 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -744,6 +744,10 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) current_shader->has_object_dependency = true; } + if(node->has_attribute_dependency()) { + current_shader->has_attribute_dependency = true; + } + if(node->has_integrator_dependency()) { current_shader->has_integrator_dependency = true; } @@ -991,6 +995,14 @@ void OSLCompiler::parameter_color_array(const char *name, const array& f ss->Parameter(name, type, table.data()); } +void OSLCompiler::parameter_attribute(const char *name, ustring s) +{ + if(Attribute::name_standard(s.c_str())) + parameter(name, (string("geom:") + s.c_str()).c_str()); + else + parameter(name, s.c_str()); +} + void OSLCompiler::find_dependencies(ShaderNodeSet& dependencies, ShaderInput *input) { ShaderNode *node = (input->link)? input->link->parent: NULL; @@ -1124,6 +1136,7 @@ void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader) shader->has_surface_spatial_varying = false; shader->has_volume_spatial_varying = false; shader->has_object_dependency = false; + shader->has_attribute_dependency = false; shader->has_integrator_dependency = false; /* generate surface shader */ diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h index 2be1126fdd3..95e35dd857b 100644 --- a/intern/cycles/render/osl.h +++ b/intern/cycles/render/osl.h @@ -140,6 +140,8 @@ public: void parameter_array(const char *name, const float f[], int arraylen); void parameter_color_array(const char *name, const array& f); + void parameter_attribute(const char *name, ustring s); + ShaderType output_type() { return current_type; } bool background; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index a1ebb26eba3..578c61a3e79 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -191,6 +191,7 @@ Shader::Shader() has_surface_spatial_varying = false; has_volume_spatial_varying = false; has_object_dependency = false; + has_attribute_dependency = false; has_integrator_dependency = false; has_volume_connected = false; @@ -463,6 +464,8 @@ void ShaderManager::device_update_common(Device *device, flag |= SD_HAS_ONLY_VOLUME; if(shader->heterogeneous_volume && shader->has_volume_spatial_varying) flag |= SD_HETEROGENEOUS_VOLUME; + if(shader->has_attribute_dependency) + flag |= SD_NEED_ATTRIBUTES; if(shader->has_bssrdf_bump) flag |= SD_HAS_BSSRDF_BUMP; if(device->info.has_volume_decoupled) { diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 4a48c1347da..abd483caabc 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -121,6 +121,7 @@ public: bool has_surface_spatial_varying; bool has_volume_spatial_varying; bool has_object_dependency; + bool has_attribute_dependency; bool has_integrator_dependency; /* displacement */ diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index b678277433b..c5b4060d5c3 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -399,6 +399,12 @@ uint SVMCompiler::attribute(AttributeStandard std) return shader_manager->get_attribute_id(std); } +uint SVMCompiler::attribute_standard(ustring name) +{ + AttributeStandard std = Attribute::name_standard(name.c_str()); + return (std)? attribute(std): attribute(name); +} + bool SVMCompiler::node_skip_input(ShaderNode * /*node*/, ShaderInput *input) { /* nasty exception .. */ @@ -447,6 +453,10 @@ void SVMCompiler::generate_node(ShaderNode *node, ShaderNodeSet& done) current_shader->has_object_dependency = true; } + if(node->has_attribute_dependency()) { + current_shader->has_attribute_dependency = true; + } + if(node->has_integrator_dependency()) { current_shader->has_integrator_dependency = true; } @@ -830,6 +840,7 @@ void SVMCompiler::compile(Scene *scene, shader->has_surface_spatial_varying = false; shader->has_volume_spatial_varying = false; shader->has_object_dependency = false; + shader->has_attribute_dependency = false; shader->has_integrator_dependency = false; /* generate bump shader */ diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h index 0e9905957c7..18be0fa9a22 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -117,6 +117,7 @@ public: void add_node(const float4& f); uint attribute(ustring name); uint attribute(AttributeStandard std); + uint attribute_standard(ustring name); uint encode_uchar4(uint x, uint y = 0, uint z = 0, uint w = 0); uint closure_mix_weight_offset() { return mix_weight_offset; } -- cgit v1.2.3