Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render/nodes.cpp')
-rw-r--r--intern/cycles/render/nodes.cpp230
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;