diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 6bfaf48c0c9..8e844bc788e 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -85,9 +85,10 @@ bool ImageManager::set_animation_frame_update(int frame) return false; } -bool ImageManager::is_float_image(const string& filename, void *builtin_data) +bool ImageManager::is_float_image(const string& filename, void *builtin_data, bool& is_linear) { bool is_float = false; + is_linear = false; if(builtin_data) { if(builtin_image_info_cb) { @@ -95,6 +96,9 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data) builtin_image_info_cb(filename, builtin_data, is_float, width, height, channels); } + if(is_float) + is_linear = true; + return is_float; } @@ -106,14 +110,30 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data) if(in->open(filename, spec)) { /* check the main format, and channel formats; * if any take up more than one byte, we'll need a float texture slot */ - if(spec.format.basesize() > 1) + if(spec.format.basesize() > 1) { is_float = true; + is_linear = true; + } for(size_t channel = 0; channel < spec.channelformats.size(); channel++) { - if(spec.channelformats[channel].basesize() > 1) + if(spec.channelformats[channel].basesize() > 1) { is_float = true; + is_linear = true; + } } + /* basic color space detection, not great but better than nothing + * before we do OpenColorIO integration */ + if(is_float) { + string colorspace = spec.get_string_attribute("oiio:ColorSpace"); + + is_linear = !(colorspace == "sRGB" || + colorspace == "GammaCorrected" || + strcmp(in->format_name(), "png") == 0); + } + else + is_linear = false; + in->close(); } @@ -123,13 +143,13 @@ bool ImageManager::is_float_image(const string& filename, void *builtin_data) return is_float; } -int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float) +int ImageManager::add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear) { Image *img; size_t slot; /* load image info and find out if we need a float texture */ - is_float = (pack_images)? false: is_float_image(filename, builtin_data); + is_float = (pack_images)? false: is_float_image(filename, builtin_data, is_linear); if(is_float) { /* find existing image */ diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 464b87ff530..b20ff23fbbb 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -51,9 +51,9 @@ public: ImageManager(); ~ImageManager(); - int add_image(const string& filename, void *builtin_data, bool animated, bool& is_float); + int add_image(const string& filename, void *builtin_data, bool animated, bool& is_float, bool& is_linear); void remove_image(const string& filename, void *builtin_data); - bool is_float_image(const string& filename, void *builtin_data); + bool is_float_image(const string& filename, void *builtin_data, bool& is_linear); void device_update(Device *device, DeviceScene *dscene, Progress& progress); void device_free(Device *device, DeviceScene *dscene); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index a0a933ef682..8ac12242e15 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -141,6 +141,7 @@ ImageTextureNode::ImageTextureNode() image_manager = NULL; slot = -1; is_float = -1; + is_linear = false; filename = ""; builtin_data = NULL; color_space = ustring("Color"); @@ -165,6 +166,7 @@ ShaderNode *ImageTextureNode::clone() const node->image_manager = NULL; node->slot = -1; node->is_float = -1; + node->is_linear = false; return node; } @@ -177,7 +179,7 @@ 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, is_float_bool); + slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool, is_linear); is_float = (int)is_float_bool; } @@ -189,7 +191,7 @@ void ImageTextureNode::compile(SVMCompiler& compiler) if(slot != -1) { compiler.stack_assign(vector_in); - int srgb = (is_float || color_space != "Color")? 0: 1; + int srgb = (is_linear || color_space != "Color")? 0: 1; int vector_offset = vector_in->stack_offset; if(!tex_mapping.skip()) { @@ -238,10 +240,10 @@ void ImageTextureNode::compile(OSLCompiler& compiler) tex_mapping.compile(compiler); if(is_float == -1) - is_float = (int)image_manager->is_float_image(filename, NULL); + is_float = (int)image_manager->is_float_image(filename, NULL, is_linear); compiler.parameter("filename", filename.c_str()); - if(is_float || color_space != "Color") + if(is_linear || color_space != "Color") compiler.parameter("color_space", "Linear"); else compiler.parameter("color_space", "sRGB"); @@ -271,6 +273,7 @@ EnvironmentTextureNode::EnvironmentTextureNode() image_manager = NULL; slot = -1; is_float = -1; + is_linear = false; filename = ""; builtin_data = NULL; color_space = ustring("Color"); @@ -294,6 +297,7 @@ ShaderNode *EnvironmentTextureNode::clone() const node->image_manager = NULL; node->slot = -1; node->is_float = -1; + node->is_linear = false; return node; } @@ -306,7 +310,7 @@ 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, is_float_bool); + slot = image_manager->add_image(filename, builtin_data, animated, is_float_bool, is_linear); is_float = (int)is_float_bool; } @@ -318,7 +322,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler) if(slot != -1) { compiler.stack_assign(vector_in); - int srgb = (is_float || color_space != "Color")? 0: 1; + int srgb = (is_linear || color_space != "Color")? 0: 1; int vector_offset = vector_in->stack_offset; if(!tex_mapping.skip()) { @@ -356,11 +360,11 @@ void EnvironmentTextureNode::compile(OSLCompiler& compiler) tex_mapping.compile(compiler); if(is_float == -1) - is_float = (int)image_manager->is_float_image(filename, NULL); + is_float = (int)image_manager->is_float_image(filename, NULL, is_linear); compiler.parameter("filename", filename.c_str()); compiler.parameter("projection", projection); - if(is_float || color_space != "Color") + if(is_linear || color_space != "Color") compiler.parameter("color_space", "Linear"); else compiler.parameter("color_space", "sRGB"); diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 66be919d098..3609497e5ce 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -69,6 +69,7 @@ public: ImageManager *image_manager; int slot; int is_float; + bool is_linear; string filename; void *builtin_data; ustring color_space; @@ -89,6 +90,7 @@ public: ImageManager *image_manager; int slot; int is_float; + bool is_linear; string filename; void *builtin_data; ustring color_space;