Cycles: Expose image image extension mapping to the image manager
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 21 Jul 2015 19:58:19 +0000 (21:58 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 21 Jul 2015 19:58:19 +0000 (21:58 +0200)
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.

12 files changed:
intern/cycles/blender/blender_mesh.cpp
intern/cycles/blender/blender_shader.cpp
intern/cycles/device/device_cpu.cpp
intern/cycles/kernel/kernel.h
intern/cycles/kernel/kernel_compat_cpu.h
intern/cycles/kernel/kernels/cpu/kernel.cpp
intern/cycles/kernel/shaders/node_image_texture.osl
intern/cycles/render/image.cpp
intern/cycles/render/image.h
intern/cycles/render/nodes.cpp
intern/cycles/render/nodes.h
intern/cycles/util/util_types.h

index d88ebb854d22b9dba2f26251976b883d58b19809..e81170ac4111264e9bff36d57c42ef72ac99727b 100644 (file)
@@ -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)
index 6c54149164de1fcd95aaca83863c1c06eb1423fa..fe7bd76d6b45f9b709cbfc5d5179b0540be205ef 100644 (file)
@@ -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;
        }
index 013f656e31ce37bbb3d4c8a120473ed7a01dea40..ec82b3805c4e75fca0b8a00469ec0f4ea7b1b3ea 100644 (file)
@@ -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);
index 0996e51b7a03af4054b3ccefee4afb633c1183e0..5c34ddcfbcbe0cc5ca149fe02cc2300e6045838e 100644 (file)
@@ -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);
index 0bf1ed36d1ec0c263072e2f3f7f1845ef6cdec85..a780c356a187cd03b0d84fb3992ed4b3d9d08d99 100644 (file)
@@ -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
 };
index 37a73ab2f041dd30269a5dacedf55ead564f7c98..2dbd9e62ee7bf6cf5f80d46f847f2d998e21c03f 100644 (file)
@@ -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
index 46a02cab32e5bbf3934537ec78a5c747eab0e81f..d3a347b70dbb874cb1d1bb9fbdd4578d041d6696 100644 (file)
@@ -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);
        }
 }
index c62afcd771909ebb915815b73a62837f29aafca3..dc9aeeefc6d891e58f857fff0f9028c20f6e34ef 100644 (file)
@@ -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);
                }
        }
 
index 70cc4935daa56b81e0d31ccbef81e872d645f5ac..bcc58ae951bf0c3dbaa6143897dced446d8fc9b2 100644 (file)
@@ -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;
        };
index 46d5b3c3684c547edf629d83ab8b24129431f3ba..1150c63a65ace804bb21c09e65880732c527712b 100644 (file)
@@ -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);
                }
 
index 5a412916e8584bf8c8cb4213c7f16246541576a9..5065e68345a79f9d834b04e8cf63f102a3733dba 100644 (file)
@@ -92,6 +92,7 @@ public:
        ustring color_space;
        ustring projection;
        InterpolationType interpolation;
+       ExtensionType extension;
        float projection_blend;
        bool animated;
 
index 187675e74bf0c93efd0529660d46370f572ef1a1..411f2d803f81a495f6837cf6f38f1188785e7fd6 100644 (file)
@@ -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_ */