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.
This commit is contained in:
parent
dc3563ff48
commit
f2c54df625
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ public:
|
|||
ustring color_space;
|
||||
ustring projection;
|
||||
InterpolationType interpolation;
|
||||
ExtensionType extension;
|
||||
float projection_blend;
|
||||
bool animated;
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue