diff options
Diffstat (limited to 'intern/cycles/render/nodes.cpp')
-rw-r--r-- | intern/cycles/render/nodes.cpp | 230 |
1 files changed, 154 insertions, 76 deletions
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index cce851612db..91fb04f1b75 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -18,6 +18,7 @@ #include "render/image.h" #include "render/integrator.h" #include "render/light.h" +#include "render/mesh.h" #include "render/nodes.h" #include "render/scene.h" #include "render/svm.h" @@ -249,21 +250,19 @@ ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type) { image_manager = NULL; - slot = -1; - is_float = -1; + is_float = false; is_linear = false; builtin_data = NULL; animated = false; + tiles.push_back(0); } ImageTextureNode::~ImageTextureNode() { if(image_manager) { - image_manager->remove_image(filename.string(), - builtin_data, - interpolation, - extension, - use_alpha); + foreach(int slot, slots) { + image_manager->remove_image(slot); + } } } @@ -271,12 +270,55 @@ ShaderNode *ImageTextureNode::clone() const { ImageTextureNode *node = new ImageTextureNode(*this); node->image_manager = NULL; - node->slot = -1; - node->is_float = -1; + node->slots.clear(); + node->is_float = false; node->is_linear = false; return node; } +void ImageTextureNode::simplify_settings(Scene *scene, Shader *shader) +{ + if(!scene->params.background) { + /* During interactive renders, all tiles are loaded. + * While we could support updating this when UVs change, that could lead + * to annoying interruptions when loading images while editing UVs. */ + return; + } + + ShaderInput *vector_in = input("Vector"); + ustring attribute; + if(vector_in->link) { + ShaderNode *node = vector_in->link->parent; + if(node->type == UVMapNode::node_type) { + UVMapNode *uvmap = (UVMapNode*) node; + attribute = uvmap->attribute; + } + else if(node->type == TextureCoordinateNode::node_type) { + if(vector_in->link != node->output("UV")) { + return; + } + } + else { + return; + } + } + + ccl::vector<bool> used_tiles; + foreach(Mesh *mesh, scene->meshes) { + if(std::find(mesh->used_shaders.begin(), mesh->used_shaders.end(), shader) != mesh->used_shaders.end()) { + mesh->get_uv_tiles(attribute, used_tiles); + } + } + + ccl::vector<int> new_tiles; + foreach(int tile, tiles) { + if (tile < used_tiles.size() && used_tiles[tile]) { + new_tiles.push_back(tile); + } + } + tiles.swap(new_tiles); +} + void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) { #ifdef WITH_PTEX @@ -299,27 +341,52 @@ void ImageTextureNode::compile(SVMCompiler& compiler) ShaderOutput *alpha_out = output("Alpha"); image_manager = compiler.image_manager; - if(is_float == -1) { - ImageMetaData metadata; - slot = image_manager->add_image(filename.string(), - builtin_data, - animated, - 0, - interpolation, - extension, - use_alpha, - metadata); - is_float = metadata.is_float; - is_linear = metadata.is_linear; + if(slots.size() < tiles.size()) { + slots.clear(); + foreach(int tile, tiles) { + string tile_name; + if(tiles.size() == 1) { + tile_name = filename.string(); + } + else { + tile_name = string_printf(filename.c_str(), 1001 + tile); + } + printf("Loading %s\n", tile_name.c_str()); + ImageMetaData metadata; + slots.push_back(image_manager->add_image(tile_name, + builtin_data, + animated, + tile, + 0, + interpolation, + extension, + use_alpha, + metadata)); + if(tile == 0) { + is_float = metadata.is_float; + is_linear = metadata.is_linear; + } + } } - if(slot != -1) { + bool has_image = false; + foreach(int slot, slots) { + if(slot != -1) { + has_image = true; + break; + } + } + + if(has_image) { + int num_nodes = divide_up(slots.size(), 2); int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR)? 0: 1; int vector_offset = tex_mapping.compile_begin(compiler, vector_in); + /* TODO(lukas): Avoid extra node for common case of only one tile. */ + if(projection != NODE_IMAGE_PROJ_BOX) { compiler.add_node(NODE_TEX_IMAGE, - slot, + num_nodes, compiler.encode_uchar4( vector_offset, compiler.stack_assign_if_linked(color_out), @@ -329,7 +396,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler) } else { compiler.add_node(NODE_TEX_IMAGE_BOX, - slot, + num_nodes, compiler.encode_uchar4( vector_offset, compiler.stack_assign_if_linked(color_out), @@ -338,6 +405,21 @@ void ImageTextureNode::compile(SVMCompiler& compiler) __float_as_int(projection_blend)); } + for(int i = 0; i < num_nodes; i++) { + int4 node; + node.x = tiles[2*i]; + node.y = slots[2*i]; + if(2*i+1 < slots.size()) { + node.z = tiles[2*i+1]; + node.w = slots[2*i+1]; + } + else { + node.z = -1; + node.w = -1; + } + compiler.add_node(node.x, node.y, node.z, node.w); + } + tex_mapping.compile_end(compiler, vector_in, vector_offset); } else { @@ -360,26 +442,28 @@ void ImageTextureNode::compile(OSLCompiler& compiler) tex_mapping.compile(compiler); image_manager = compiler.image_manager; - if(is_float == -1) { + if(slots.size() == 0) { ImageMetaData metadata; if(builtin_data == NULL) { image_manager->get_image_metadata(filename.string(), NULL, metadata); + slots.push_back(-1); } else { - slot = image_manager->add_image(filename.string(), - builtin_data, - animated, - 0, - interpolation, - extension, - use_alpha, - metadata); + slots.push_back(image_manager->add_image(filename.string(), + builtin_data, + animated, + 0, + 0, + interpolation, + extension, + use_alpha, + metadata)); } is_float = metadata.is_float; is_linear = metadata.is_linear; } - if(slot == -1) { + if(slots[0] == -1) { compiler.parameter(this, "filename"); } else { @@ -389,7 +473,7 @@ void ImageTextureNode::compile(OSLCompiler& compiler) * "@i<slot_number>" and check whether file name matches this * mask in the OSLRenderServices::texture(). */ - compiler.parameter("filename", string_printf("@i%d", slot).c_str()); + compiler.parameter("filename", string_printf("@i%d", slots[0]).c_str()); } if(is_linear || color_space != NODE_COLOR_SPACE_COLOR) compiler.parameter("color_space", "linear"); @@ -446,8 +530,7 @@ EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode(node_type) { image_manager = NULL; - slot = -1; - is_float = -1; + is_float = false; is_linear = false; builtin_data = NULL; animated = false; @@ -455,12 +538,8 @@ EnvironmentTextureNode::EnvironmentTextureNode() EnvironmentTextureNode::~EnvironmentTextureNode() { - if(image_manager) { - image_manager->remove_image(filename.string(), - builtin_data, - interpolation, - EXTENSION_REPEAT, - use_alpha); + if(image_manager && slots.size()) { + image_manager->remove_image(slots[0]); } } @@ -468,8 +547,8 @@ ShaderNode *EnvironmentTextureNode::clone() const { EnvironmentTextureNode *node = new EnvironmentTextureNode(*this); node->image_manager = NULL; - node->slot = -1; - node->is_float = -1; + node->slots.clear(); + node->is_float = false; node->is_linear = false; return node; } @@ -494,26 +573,27 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler) ShaderOutput *alpha_out = output("Alpha"); image_manager = compiler.image_manager; - if(slot == -1) { + if(slots.size() == 0) { ImageMetaData metadata; - slot = image_manager->add_image(filename.string(), - builtin_data, - animated, - 0, - interpolation, - EXTENSION_REPEAT, - use_alpha, - metadata); + slots.push_back(image_manager->add_image(filename.string(), + builtin_data, + animated, + 0, + 0, + interpolation, + EXTENSION_REPEAT, + use_alpha, + metadata)); is_float = metadata.is_float; is_linear = metadata.is_linear; } - if(slot != -1) { + if(slots[0] != -1) { int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR)? 0: 1; int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.add_node(NODE_TEX_ENVIRONMENT, - slot, + slots[0], compiler.encode_uchar4( vector_offset, compiler.stack_assign_if_linked(color_out), @@ -546,30 +626,32 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler) * of builtin images. */ image_manager = compiler.image_manager; - if(is_float == -1) { + if(slots.size() == 0) { + slots.resize(1); ImageMetaData metadata; if(builtin_data == NULL) { image_manager->get_image_metadata(filename.string(), NULL, metadata); } else { - slot = image_manager->add_image(filename.string(), - builtin_data, - animated, - 0, - interpolation, - EXTENSION_REPEAT, - use_alpha, - metadata); + slots[0] = image_manager->add_image(filename.string(), + builtin_data, + animated, + 0, + 0, + interpolation, + EXTENSION_REPEAT, + use_alpha, + metadata); } is_float = metadata.is_float; is_linear = metadata.is_linear; } - if(slot == -1) { + if(slots[0] == -1) { compiler.parameter(this, "filename"); } else { - compiler.parameter("filename", string_printf("@i%d", slot).c_str()); + compiler.parameter("filename", string_printf("@i%d", slots[0]).c_str()); } compiler.parameter(this, "projection"); if(is_linear || color_space != NODE_COLOR_SPACE_COLOR) @@ -1495,11 +1577,7 @@ PointDensityTextureNode::PointDensityTextureNode() PointDensityTextureNode::~PointDensityTextureNode() { if(image_manager) { - image_manager->remove_image(filename.string(), - builtin_data, - interpolation, - EXTENSION_CLIP, - true); + image_manager->remove_image(slot); } } @@ -1525,7 +1603,7 @@ void PointDensityTextureNode::add_image() if(slot == -1) { ImageMetaData metadata; slot = image_manager->add_image(filename.string(), builtin_data, - false, 0, + false, 0, 0, interpolation, EXTENSION_CLIP, true, @@ -2055,7 +2133,7 @@ GlossyBsdfNode::GlossyBsdfNode() distribution_orig = NBUILTIN_CLOSURES; } -void GlossyBsdfNode::simplify_settings(Scene *scene) +void GlossyBsdfNode::simplify_settings(Scene *scene, Shader * /*shader*/) { if(distribution_orig == NBUILTIN_CLOSURES) { roughness_orig = roughness; @@ -2150,7 +2228,7 @@ GlassBsdfNode::GlassBsdfNode() distribution_orig = NBUILTIN_CLOSURES; } -void GlassBsdfNode::simplify_settings(Scene *scene) +void GlassBsdfNode::simplify_settings(Scene *scene, Shader * /*shader*/) { if(distribution_orig == NBUILTIN_CLOSURES) { roughness_orig = roughness; @@ -2245,7 +2323,7 @@ RefractionBsdfNode::RefractionBsdfNode() distribution_orig = NBUILTIN_CLOSURES; } -void RefractionBsdfNode::simplify_settings(Scene *scene) +void RefractionBsdfNode::simplify_settings(Scene *scene, Shader * /*shader*/) { if(distribution_orig == NBUILTIN_CLOSURES) { roughness_orig = roughness; |