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:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-07-21 22:58:19 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-07-21 22:58:19 +0300
commitf2c54df625d65c40f6070294a5f66de3f2d18c10 (patch)
tree1f5b12ba40e6e9b563d84c9df5ebe47b24ead20e
parentdc3563ff4801907ec8cd21a1589f0cb56d021a8f (diff)
Cycles: Expose image image extension mapping to the image manager
Currently only two mappings are supported by API, which is Repeat (old behavior) and new Clip behavior. Internally this extension is being converted to periodic flag which was already supported but wasn't exposed. There's no support for OpenCL yet because of the way how we pack images into a single texture. Those settings are not exposed to UI or anywhere else and there should be no functional changes so far.
-rw-r--r--intern/cycles/blender/blender_mesh.cpp12
-rw-r--r--intern/cycles/blender/blender_shader.cpp20
-rw-r--r--intern/cycles/device/device_cpu.cpp14
-rw-r--r--intern/cycles/kernel/kernel.h9
-rw-r--r--intern/cycles/kernel/kernel_compat_cpu.h10
-rw-r--r--intern/cycles/kernel/kernels/cpu/kernel.cpp11
-rw-r--r--intern/cycles/kernel/shaders/node_image_texture.osl66
-rw-r--r--intern/cycles/render/image.cpp81
-rw-r--r--intern/cycles/render/image.h22
-rw-r--r--intern/cycles/render/nodes.cpp83
-rw-r--r--intern/cycles/render/nodes.h1
-rw-r--r--intern/cycles/util/util_types.h11
12 files changed, 276 insertions, 64 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index d88ebb854d2..e81170ac411 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -242,8 +242,16 @@ static void create_mesh_volume_attribute(BL::Object b_ob, Mesh *mesh, ImageManag
bool animated = false;
volume_data->manager = image_manager;
- volume_data->slot = image_manager->add_image(Attribute::standard_name(std),
- b_ob.ptr.data, animated, frame, is_float, is_linear, INTERPOLATION_LINEAR, true);
+ volume_data->slot = image_manager->add_image(
+ Attribute::standard_name(std),
+ b_ob.ptr.data,
+ animated,
+ frame,
+ is_float,
+ is_linear,
+ INTERPOLATION_LINEAR,
+ EXTENSION_REPEAT,
+ true);
}
static void create_mesh_volume_attributes(Scene *scene, BL::Object b_ob, Mesh *mesh, float frame)
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 6c54149164d..fe7bd76d6b4 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -590,14 +590,17 @@ static ShaderNode *add_node(Scene *scene,
/* TODO(sergey): Does not work properly when we change builtin type. */
if(b_image.is_updated()) {
- scene->image_manager->tag_reload_image(image->filename,
- image->builtin_data,
- (InterpolationType)b_image_node.interpolation());
+ scene->image_manager->tag_reload_image(
+ image->filename,
+ image->builtin_data,
+ (InterpolationType)b_image_node.interpolation(),
+ EXTENSION_REPEAT);
}
}
image->color_space = ImageTextureNode::color_space_enum[(int)b_image_node.color_space()];
image->projection = ImageTextureNode::projection_enum[(int)b_image_node.projection()];
image->interpolation = (InterpolationType)b_image_node.interpolation();
+ image->extension = EXTENSION_REPEAT;
image->projection_blend = b_image_node.projection_blend();
get_tex_mapping(&image->tex_mapping, b_image_node.texture_mapping());
node = image;
@@ -630,7 +633,8 @@ static ShaderNode *add_node(Scene *scene,
if(b_image.is_updated()) {
scene->image_manager->tag_reload_image(env->filename,
env->builtin_data,
- INTERPOLATION_LINEAR);
+ INTERPOLATION_LINEAR,
+ EXTENSION_REPEAT);
}
}
env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
@@ -759,9 +763,11 @@ static ShaderNode *add_node(Scene *scene,
/* TODO(sergey): Use more proper update flag. */
if(true) {
- scene->image_manager->tag_reload_image(point_density->filename,
- point_density->builtin_data,
- point_density->interpolation);
+ scene->image_manager->tag_reload_image(
+ point_density->filename,
+ point_density->builtin_data,
+ point_density->interpolation,
+ EXTENSION_CLIP);
}
node = point_density;
}
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 013f656e31c..ec82b3805c4 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -123,10 +123,20 @@ public:
kernel_const_copy(&kernel_globals, name, host, size);
}
- void tex_alloc(const char *name, device_memory& mem, InterpolationType interpolation, bool /*periodic*/)
+ void tex_alloc(const char *name,
+ device_memory& mem,
+ InterpolationType interpolation,
+ bool periodic)
{
VLOG(1) << "Texture allocate: " << name << ", " << mem.memory_size() << " bytes.";
- kernel_tex_copy(&kernel_globals, name, mem.data_pointer, mem.data_width, mem.data_height, mem.data_depth, interpolation);
+ kernel_tex_copy(&kernel_globals,
+ name,
+ mem.data_pointer,
+ mem.data_width,
+ mem.data_height,
+ mem.data_depth,
+ interpolation,
+ periodic);
mem.device_pointer = mem.data_pointer;
mem.device_size = mem.memory_size();
stats.mem_alloc(mem.device_size);
diff --git a/intern/cycles/kernel/kernel.h b/intern/cycles/kernel/kernel.h
index 0996e51b7a0..5c34ddcfbcb 100644
--- a/intern/cycles/kernel/kernel.h
+++ b/intern/cycles/kernel/kernel.h
@@ -32,7 +32,14 @@ void *kernel_osl_memory(KernelGlobals *kg);
bool kernel_osl_use(KernelGlobals *kg);
void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size);
-void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height, size_t depth, InterpolationType interpolation=INTERPOLATION_LINEAR);
+void kernel_tex_copy(KernelGlobals *kg,
+ const char *name,
+ device_ptr mem,
+ size_t width,
+ size_t height,
+ size_t depth,
+ InterpolationType interpolation=INTERPOLATION_LINEAR,
+ bool periodic = true);
void kernel_cpu_path_trace(KernelGlobals *kg, float *buffer, unsigned int *rng_state,
int sample, int x, int y, int offset, int stride);
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index 0bf1ed36d1e..a780c356a18 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -128,7 +128,7 @@ template<typename T> struct texture_image {
return x - (float)i;
}
- ccl_always_inline float4 interp(float x, float y, bool periodic = true)
+ ccl_always_inline float4 interp(float x, float y)
{
if(UNLIKELY(!data))
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
@@ -233,14 +233,13 @@ template<typename T> struct texture_image {
}
}
- ccl_always_inline float4 interp_3d(float x, float y, float z, bool periodic = false)
+ ccl_always_inline float4 interp_3d(float x, float y, float z)
{
- return interp_3d_ex(x, y, z, interpolation, periodic);
+ return interp_3d_ex(x, y, z, interpolation);
}
ccl_always_inline float4 interp_3d_ex(float x, float y, float z,
- int interpolation = INTERPOLATION_LINEAR,
- bool periodic = false)
+ int interpolation = INTERPOLATION_LINEAR)
{
if(UNLIKELY(!data))
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
@@ -393,6 +392,7 @@ template<typename T> struct texture_image {
T *data;
int interpolation;
+ bool periodic;
int width, height, depth;
#undef SET_CUBIC_SPLINE_WEIGHTS
};
diff --git a/intern/cycles/kernel/kernels/cpu/kernel.cpp b/intern/cycles/kernel/kernels/cpu/kernel.cpp
index 37a73ab2f04..2dbd9e62ee7 100644
--- a/intern/cycles/kernel/kernels/cpu/kernel.cpp
+++ b/intern/cycles/kernel/kernels/cpu/kernel.cpp
@@ -38,7 +38,14 @@ void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t s
assert(0);
}
-void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height, size_t depth, InterpolationType interpolation)
+void kernel_tex_copy(KernelGlobals *kg,
+ const char *name,
+ device_ptr mem,
+ size_t width,
+ size_t height,
+ size_t depth,
+ InterpolationType interpolation,
+ bool periodic)
{
if(0) {
}
@@ -64,6 +71,7 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t
tex->data = (float4*)mem;
tex->dimensions_set(width, height, depth);
tex->interpolation = interpolation;
+ tex->periodic = periodic;
}
}
else if(strstr(name, "__tex_image")) {
@@ -79,6 +87,7 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t
tex->data = (uchar4*)mem;
tex->dimensions_set(width, height, depth);
tex->interpolation = interpolation;
+ tex->periodic = periodic;
}
}
else
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl
index 46a02cab32e..d3a347b70db 100644
--- a/intern/cycles/kernel/shaders/node_image_texture.osl
+++ b/intern/cycles/kernel/shaders/node_image_texture.osl
@@ -55,9 +55,16 @@ point map_to_sphere(vector dir)
return point(u, v, 0.0);
}
-color image_texture_lookup(string filename, string color_space, float u, float v, output float Alpha, int use_alpha, int is_float, string interpolation)
+color image_texture_lookup(string filename,
+ string color_space,
+ float u, float v,
+ output float Alpha,
+ int use_alpha,
+ int is_float,
+ string interpolation,
+ string wrap)
{
- color rgb = (color)texture(filename, u, 1.0 - v, "wrap", "periodic", "interp", interpolation, "alpha", Alpha);
+ color rgb = (color)texture(filename, u, 1.0 - v, "wrap", wrap, "interp", interpolation, "alpha", Alpha);
if (use_alpha) {
rgb = color_unpremultiply(rgb, Alpha);
@@ -81,6 +88,7 @@ shader node_image_texture(
string color_space = "sRGB",
string projection = "Flat",
string interpolation = "smartcubic",
+ string wrap = "periodic",
float projection_blend = 0.0,
int is_float = 1,
int use_alpha = 1,
@@ -93,7 +101,14 @@ shader node_image_texture(
p = transform(mapping, p);
if (projection == "Flat") {
- Color = image_texture_lookup(filename, color_space, p[0], p[1], Alpha, use_alpha, is_float, interpolation);
+ Color = image_texture_lookup(filename,
+ color_space,
+ p[0], p[1],
+ Alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ wrap);
}
else if (projection == "Box") {
/* object space normal */
@@ -162,28 +177,59 @@ shader node_image_texture(
float tmp_alpha;
if (weight[0] > 0.0) {
- Color += weight[0] * image_texture_lookup(filename, color_space, p[1], p[2], tmp_alpha, use_alpha, is_float, interpolation);
+ Color += weight[0] * image_texture_lookup(filename,
+ color_space,
+ p[1], p[2],
+ tmp_alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ wrap);
Alpha += weight[0] * tmp_alpha;
}
if (weight[1] > 0.0) {
- Color += weight[1] * image_texture_lookup(filename, color_space, p[0], p[2], tmp_alpha, use_alpha, is_float, interpolation);
+ Color += weight[1] * image_texture_lookup(filename,
+ color_space,
+ p[0], p[2],
+ tmp_alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ wrap);
Alpha += weight[1] * tmp_alpha;
}
if (weight[2] > 0.0) {
- Color += weight[2] * image_texture_lookup(filename, color_space, p[1], p[0], tmp_alpha, use_alpha, is_float, interpolation);
+ Color += weight[2] * image_texture_lookup(filename,
+ color_space,
+ p[1], p[0],
+ tmp_alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ wrap);
Alpha += weight[2] * tmp_alpha;
}
}
else if (projection == "Sphere") {
point projected = map_to_sphere(texco_remap_square(p));
- Color = image_texture_lookup(filename, color_space,
+ Color = image_texture_lookup(filename,
+ color_space,
projected[0], projected[1],
- Alpha, use_alpha, is_float, interpolation);
+ Alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ wrap);
}
else if (projection == "Tube") {
point projected = map_to_tube(texco_remap_square(p));
- Color = image_texture_lookup(filename, color_space,
+ Color = image_texture_lookup(filename,
+ color_space,
projected[0], projected[1],
- Alpha, use_alpha, is_float, interpolation);
+ Alpha,
+ use_alpha,
+ is_float,
+ interpolation,
+ wrap);
}
}
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index c62afcd7719..dc9aeeefc6d 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -151,15 +151,27 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data, bo
return is_float;
}
-static bool image_equals(ImageManager::Image *image, const string& filename, void *builtin_data, InterpolationType interpolation)
+static bool image_equals(ImageManager::Image *image,
+ const string& filename,
+ void *builtin_data,
+ InterpolationType interpolation,
+ ExtensionType extension)
{
return image->filename == filename &&
image->builtin_data == builtin_data &&
- image->interpolation == interpolation;
+ image->interpolation == interpolation &&
+ image->extension == extension;
}
-int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, float frame,
- bool& is_float, bool& is_linear, InterpolationType interpolation, bool use_alpha)
+int ImageManager::add_image(const string& filename,
+ void *builtin_data,
+ bool animated,
+ float frame,
+ bool& is_float,
+ bool& is_linear,
+ InterpolationType interpolation,
+ ExtensionType extension,
+ bool use_alpha)
{
Image *img;
size_t slot;
@@ -171,7 +183,12 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani
/* find existing image */
for(slot = 0; slot < float_images.size(); slot++) {
img = float_images[slot];
- if(img && image_equals(img, filename, builtin_data, interpolation)) {
+ if(img && image_equals(img,
+ filename,
+ builtin_data,
+ interpolation,
+ extension))
+ {
if(img->frame != frame) {
img->frame = frame;
img->need_load = true;
@@ -210,6 +227,7 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani
img->animated = animated;
img->frame = frame;
img->interpolation = interpolation;
+ img->extension = extension;
img->users = 1;
img->use_alpha = use_alpha;
@@ -218,7 +236,12 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani
else {
for(slot = 0; slot < images.size(); slot++) {
img = images[slot];
- if(img && image_equals(img, filename, builtin_data, interpolation)) {
+ if(img && image_equals(img,
+ filename,
+ builtin_data,
+ interpolation,
+ extension))
+ {
if(img->frame != frame) {
img->frame = frame;
img->need_load = true;
@@ -257,6 +280,7 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani
img->animated = animated;
img->frame = frame;
img->interpolation = interpolation;
+ img->extension = extension;
img->users = 1;
img->use_alpha = use_alpha;
@@ -300,12 +324,20 @@ void ImageManager::remove_image(int slot)
}
}
-void ImageManager::remove_image(const string& filename, void *builtin_data, InterpolationType interpolation)
+void ImageManager::remove_image(const string& filename,
+ void *builtin_data,
+ InterpolationType interpolation,
+ ExtensionType extension)
{
size_t slot;
for(slot = 0; slot < images.size(); slot++) {
- if(images[slot] && image_equals(images[slot], filename, builtin_data, interpolation)) {
+ if(images[slot] && image_equals(images[slot],
+ filename,
+ builtin_data,
+ interpolation,
+ extension))
+ {
remove_image(slot+tex_image_byte_start);
break;
}
@@ -314,7 +346,11 @@ void ImageManager::remove_image(const string& filename, void *builtin_data, Inte
if(slot == images.size()) {
/* see if it's in a float texture slot */
for(slot = 0; slot < float_images.size(); slot++) {
- if(float_images[slot] && image_equals(float_images[slot], filename, builtin_data, interpolation)) {
+ if(float_images[slot] && image_equals(float_images[slot],
+ filename,
+ builtin_data,
+ interpolation,
+ extension)) {
remove_image(slot);
break;
}
@@ -326,12 +362,19 @@ void ImageManager::remove_image(const string& filename, void *builtin_data, Inte
* without bunch of arguments passing around making code readability even
* more cluttered.
*/
-void ImageManager::tag_reload_image(const string& filename, void *builtin_data, InterpolationType interpolation)
+void ImageManager::tag_reload_image(const string& filename,
+ void *builtin_data,
+ InterpolationType interpolation,
+ ExtensionType extension)
{
size_t slot;
for(slot = 0; slot < images.size(); slot++) {
- if(images[slot] && image_equals(images[slot], filename, builtin_data, interpolation)) {
+ if(images[slot] && image_equals(images[slot],
+ filename,
+ builtin_data,
+ interpolation,
+ extension)) {
images[slot]->need_load = true;
break;
}
@@ -340,7 +383,11 @@ void ImageManager::tag_reload_image(const string& filename, void *builtin_data,
if(slot == images.size()) {
/* see if it's in a float texture slot */
for(slot = 0; slot < float_images.size(); slot++) {
- if(float_images[slot] && image_equals(float_images[slot], filename, builtin_data, interpolation)) {
+ if(float_images[slot] && image_equals(float_images[slot],
+ filename,
+ builtin_data,
+ interpolation,
+ extension)) {
float_images[slot]->need_load = true;
break;
}
@@ -664,7 +711,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl
if(!pack_images) {
thread_scoped_lock device_lock(device_mutex);
- device->tex_alloc(name.c_str(), tex_img, img->interpolation, true);
+ device->tex_alloc(name.c_str(),
+ tex_img,
+ img->interpolation,
+ img->extension == EXTENSION_REPEAT);
}
}
else {
@@ -696,7 +746,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl
if(!pack_images) {
thread_scoped_lock device_lock(device_mutex);
- device->tex_alloc(name.c_str(), tex_img, img->interpolation, true);
+ device->tex_alloc(name.c_str(),
+ tex_img,
+ img->interpolation,
+ img->extension == EXTENSION_REPEAT);
}
}
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 70cc4935daa..bcc58ae951b 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -55,11 +55,24 @@ public:
ImageManager();
~ImageManager();
- int add_image(const string& filename, void *builtin_data, bool animated, float frame,
- bool& is_float, bool& is_linear, InterpolationType interpolation, bool use_alpha);
+ int add_image(const string& filename,
+ void *builtin_data,
+ bool animated,
+ float frame,
+ bool& is_float,
+ bool& is_linear,
+ InterpolationType interpolation,
+ ExtensionType extension,
+ bool use_alpha);
void remove_image(int slot);
- void remove_image(const string& filename, void *builtin_data, InterpolationType interpolation);
- void tag_reload_image(const string& filename, void *builtin_data, InterpolationType interpolation);
+ void remove_image(const string& filename,
+ void *builtin_data,
+ InterpolationType interpolation,
+ ExtensionType extension);
+ void tag_reload_image(const string& filename,
+ void *builtin_data,
+ InterpolationType interpolation,
+ ExtensionType extension);
bool is_float_image(const string& filename, void *builtin_data, bool& is_linear);
void device_update(Device *device, DeviceScene *dscene, Progress& progress);
@@ -87,6 +100,7 @@ public:
bool animated;
float frame;
InterpolationType interpolation;
+ ExtensionType extension;
int users;
};
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 46d5b3c3684..1150c63a65a 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -198,6 +198,7 @@ ImageTextureNode::ImageTextureNode()
color_space = ustring("Color");
projection = ustring("Flat");
interpolation = INTERPOLATION_LINEAR;
+ extension = EXTENSION_REPEAT;
projection_blend = 0.0f;
animated = false;
@@ -208,8 +209,12 @@ ImageTextureNode::ImageTextureNode()
ImageTextureNode::~ImageTextureNode()
{
- if(image_manager)
- image_manager->remove_image(filename, builtin_data, interpolation);
+ if(image_manager) {
+ image_manager->remove_image(filename,
+ builtin_data,
+ interpolation,
+ extension);
+ }
}
ShaderNode *ImageTextureNode::clone() const
@@ -246,9 +251,15 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(is_float == -1) {
bool is_float_bool;
- slot = image_manager->add_image(filename, builtin_data,
- animated, 0, is_float_bool, is_linear,
- interpolation, use_alpha);
+ slot = image_manager->add_image(filename,
+ builtin_data,
+ animated,
+ 0,
+ is_float_bool,
+ is_linear,
+ interpolation,
+ extension,
+ use_alpha);
is_float = (int)is_float_bool;
}
@@ -318,9 +329,15 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
}
else {
bool is_float_bool;
- slot = image_manager->add_image(filename, builtin_data,
- animated, 0, is_float_bool, is_linear,
- interpolation, use_alpha);
+ slot = image_manager->add_image(filename,
+ builtin_data,
+ animated,
+ 0,
+ is_float_bool,
+ is_linear,
+ interpolation,
+ extension,
+ use_alpha);
is_float = (int)is_float_bool;
}
}
@@ -361,6 +378,14 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
compiler.parameter("interpolation", "linear");
break;
}
+
+ if (extension == EXTENSION_REPEAT) {
+ compiler.parameter("wrap", "periodic");
+ }
+ else {
+ compiler.parameter("wrap", "clamp");
+ }
+
compiler.add(this, "node_image_texture");
}
@@ -400,8 +425,12 @@ EnvironmentTextureNode::EnvironmentTextureNode()
EnvironmentTextureNode::~EnvironmentTextureNode()
{
- if(image_manager)
- image_manager->remove_image(filename, builtin_data, INTERPOLATION_LINEAR);
+ if(image_manager) {
+ image_manager->remove_image(filename,
+ builtin_data,
+ INTERPOLATION_LINEAR,
+ EXTENSION_REPEAT);
+ }
}
ShaderNode *EnvironmentTextureNode::clone() const
@@ -436,9 +465,15 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(slot == -1) {
bool is_float_bool;
- slot = image_manager->add_image(filename, builtin_data,
- animated, 0, is_float_bool, is_linear,
- INTERPOLATION_LINEAR, use_alpha);
+ slot = image_manager->add_image(filename,
+ builtin_data,
+ animated,
+ 0,
+ is_float_bool,
+ is_linear,
+ INTERPOLATION_LINEAR,
+ EXTENSION_REPEAT,
+ use_alpha);
is_float = (int)is_float_bool;
}
@@ -499,9 +534,15 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler)
}
else {
bool is_float_bool;
- slot = image_manager->add_image(filename, builtin_data,
- animated, 0, is_float_bool, is_linear,
- INTERPOLATION_LINEAR, use_alpha);
+ slot = image_manager->add_image(filename,
+ builtin_data,
+ animated,
+ 0,
+ is_float_bool,
+ is_linear,
+ INTERPOLATION_LINEAR,
+ EXTENSION_REPEAT,
+ use_alpha);
is_float = (int)is_float_bool;
}
}
@@ -1330,8 +1371,12 @@ PointDensityTextureNode::PointDensityTextureNode()
PointDensityTextureNode::~PointDensityTextureNode()
{
- if(image_manager)
- image_manager->remove_image(filename, builtin_data, interpolation);
+ if(image_manager) {
+ image_manager->remove_image(filename,
+ builtin_data,
+ interpolation,
+ EXTENSION_CLIP);
+ }
}
ShaderNode *PointDensityTextureNode::clone() const
@@ -1374,6 +1419,7 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler)
false, 0,
is_float, is_linear,
interpolation,
+ EXTENSION_CLIP,
true);
}
@@ -1421,6 +1467,7 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler)
false, 0,
is_float, is_linear,
interpolation,
+ EXTENSION_CLIP,
true);
}
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 5a412916e85..5065e68345a 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -92,6 +92,7 @@ public:
ustring color_space;
ustring projection;
InterpolationType interpolation;
+ ExtensionType extension;
float projection_blend;
bool animated;
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index 187675e74bf..411f2d803f8 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -470,6 +470,17 @@ enum InterpolationType {
INTERPOLATION_SMART = 3,
};
+/* Extension types for textures.
+ *
+ * Defines how the image is extrapolated past its original bounds.
+ */
+enum ExtensionType {
+ /* Cause the image to repeat horizontally and vertically. */
+ EXTENSION_REPEAT = 0,
+ /* Clip to image size and set exterior pixels as transparent. */
+ EXTENSION_CLIP = 1,
+};
+
/* macros */
/* hints for branch prediction, only use in code that runs a _lot_ */