diff options
author | Lukas Stockner <lukas.stockner@freenet.de> | 2019-05-02 16:45:31 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-05-03 16:42:49 +0300 |
commit | 68b15fc3ad4f74be192150d3a2fb35e7ef2d4edd (patch) | |
tree | 26c2aa7b37c3520417acf13b4a80c3023346b1c2 /intern/cycles/render/nodes.cpp | |
parent | dba4684f82a179a5c8abdae5940bc7c35e65a1a7 (diff) |
Cycles: support loading images from arbitrary OpenColorIO color space
These are the internal changes to Cycles, for Blender integration there are no
functional changes in this commit.
Images are converted to scene linear color space on file load, and on reading
from the OpenImageIO texture cache. 8-bit images are compressed with the sRGB
transfer function to avoid precision loss while keeping memory usages low. This
also means that for common cases of 8-bit sRGB images no conversion happens at
all on image loading.
Initial patch by Lukas, completed by Brecht.
Differential Revision: https://developer.blender.org/D3491
Diffstat (limited to 'intern/cycles/render/nodes.cpp')
-rw-r--r-- | intern/cycles/render/nodes.cpp | 99 |
1 files changed, 57 insertions, 42 deletions
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 35e9f8df5a8..6e86643cc2b 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "render/colorspace.h" #include "render/film.h" #include "render/image.h" #include "render/integrator.h" @@ -207,11 +208,7 @@ NODE_DEFINE(ImageTextureNode) TEXTURE_MAPPING_DEFINE(ImageTextureNode); SOCKET_STRING(filename, "Filename", ustring()); - - static NodeEnum color_space_enum; - color_space_enum.insert("none", NODE_COLOR_SPACE_NONE); - color_space_enum.insert("color", NODE_COLOR_SPACE_COLOR); - SOCKET_ENUM(color_space, "Color Space", color_space_enum, NODE_COLOR_SPACE_COLOR); + SOCKET_STRING(colorspace, "Colorspace", u_colorspace_auto); SOCKET_BOOLEAN(use_alpha, "Use Alpha", true); @@ -250,7 +247,8 @@ ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type) image_manager = NULL; slot = -1; is_float = -1; - is_linear = false; + compress_as_srgb = false; + colorspace = u_colorspace_raw; builtin_data = NULL; animated = false; } @@ -259,7 +257,7 @@ ImageTextureNode::~ImageTextureNode() { if (image_manager) { image_manager->remove_image( - filename.string(), builtin_data, interpolation, extension, use_alpha); + filename.string(), builtin_data, interpolation, extension, use_alpha, colorspace); } } @@ -269,7 +267,8 @@ ShaderNode *ImageTextureNode::clone() const node->image_manager = NULL; node->slot = -1; node->is_float = -1; - node->is_linear = false; + node->compress_as_srgb = false; + node->colorspace = u_colorspace_raw; return node; } @@ -304,13 +303,14 @@ void ImageTextureNode::compile(SVMCompiler &compiler) interpolation, extension, use_alpha, + colorspace, metadata); is_float = metadata.is_float; - is_linear = metadata.is_linear; + compress_as_srgb = metadata.compress_as_srgb; + colorspace = metadata.colorspace; } if (slot != -1) { - int srgb = (is_linear || color_space != NODE_COLOR_SPACE_COLOR) ? 0 : 1; int vector_offset = tex_mapping.compile_begin(compiler, vector_in); if (projection != NODE_IMAGE_PROJ_BOX) { @@ -319,7 +319,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler) compiler.encode_uchar4(vector_offset, compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(alpha_out), - srgb), + compress_as_srgb), projection); } else { @@ -328,7 +328,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler) compiler.encode_uchar4(vector_offset, compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(alpha_out), - srgb), + compress_as_srgb), __float_as_int(projection_blend)); } @@ -358,7 +358,7 @@ void ImageTextureNode::compile(OSLCompiler &compiler) if (is_float == -1) { ImageMetaData metadata; if (builtin_data == NULL) { - image_manager->get_image_metadata(filename.string(), NULL, metadata); + image_manager->get_image_metadata(filename.string(), NULL, colorspace, metadata); } else { slot = image_manager->add_image(filename.string(), @@ -368,17 +368,22 @@ void ImageTextureNode::compile(OSLCompiler &compiler) interpolation, extension, use_alpha, + colorspace, metadata); } is_float = metadata.is_float; - is_linear = metadata.is_linear; + compress_as_srgb = metadata.compress_as_srgb; + colorspace = metadata.colorspace; } - compiler.parameter_texture("filename", filename, slot); - if (is_linear || color_space != NODE_COLOR_SPACE_COLOR) - compiler.parameter("color_space", "linear"); - else - compiler.parameter("color_space", "sRGB"); + if (slot == -1) { + compiler.parameter_texture("filename", filename, colorspace); + } + else { + compiler.parameter_texture("filename", slot); + } + + compiler.parameter("color_space", (compress_as_srgb) ? "sRGB" : "linear"); compiler.parameter(this, "projection"); compiler.parameter(this, "projection_blend"); compiler.parameter("is_float", is_float); @@ -398,11 +403,7 @@ NODE_DEFINE(EnvironmentTextureNode) TEXTURE_MAPPING_DEFINE(EnvironmentTextureNode); SOCKET_STRING(filename, "Filename", ustring()); - - static NodeEnum color_space_enum; - color_space_enum.insert("none", NODE_COLOR_SPACE_NONE); - color_space_enum.insert("color", NODE_COLOR_SPACE_COLOR); - SOCKET_ENUM(color_space, "Color Space", color_space_enum, NODE_COLOR_SPACE_COLOR); + SOCKET_STRING(colorspace, "Colorspace", u_colorspace_auto); SOCKET_BOOLEAN(use_alpha, "Use Alpha", true); @@ -431,7 +432,8 @@ EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode(node_typ image_manager = NULL; slot = -1; is_float = -1; - is_linear = false; + compress_as_srgb = false; + colorspace = u_colorspace_raw; builtin_data = NULL; animated = false; } @@ -440,7 +442,7 @@ EnvironmentTextureNode::~EnvironmentTextureNode() { if (image_manager) { image_manager->remove_image( - filename.string(), builtin_data, interpolation, EXTENSION_REPEAT, use_alpha); + filename.string(), builtin_data, interpolation, EXTENSION_REPEAT, use_alpha, colorspace); } } @@ -450,7 +452,8 @@ ShaderNode *EnvironmentTextureNode::clone() const node->image_manager = NULL; node->slot = -1; node->is_float = -1; - node->is_linear = false; + node->compress_as_srgb = false; + node->colorspace = u_colorspace_raw; return node; } @@ -483,13 +486,14 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler) interpolation, EXTENSION_REPEAT, use_alpha, + colorspace, metadata); is_float = metadata.is_float; - is_linear = metadata.is_linear; + compress_as_srgb = metadata.compress_as_srgb; + colorspace = metadata.colorspace; } if (slot != -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, @@ -497,7 +501,7 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler) compiler.encode_uchar4(vector_offset, compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(alpha_out), - srgb), + compress_as_srgb), projection); tex_mapping.compile_end(compiler, vector_in, vector_offset); @@ -529,7 +533,7 @@ void EnvironmentTextureNode::compile(OSLCompiler &compiler) if (is_float == -1) { ImageMetaData metadata; if (builtin_data == NULL) { - image_manager->get_image_metadata(filename.string(), NULL, metadata); + image_manager->get_image_metadata(filename.string(), NULL, colorspace, metadata); } else { slot = image_manager->add_image(filename.string(), @@ -539,19 +543,23 @@ void EnvironmentTextureNode::compile(OSLCompiler &compiler) interpolation, EXTENSION_REPEAT, use_alpha, + colorspace, metadata); } is_float = metadata.is_float; - is_linear = metadata.is_linear; + compress_as_srgb = metadata.compress_as_srgb; + colorspace = metadata.colorspace; } - compiler.parameter_texture("filename", filename, slot); - compiler.parameter(this, "projection"); - if (is_linear || color_space != NODE_COLOR_SPACE_COLOR) - compiler.parameter("color_space", "linear"); - else - compiler.parameter("color_space", "sRGB"); + if (slot == -1) { + compiler.parameter_texture("filename", filename, colorspace); + } + else { + compiler.parameter_texture("filename", slot); + } + compiler.parameter(this, "projection"); + compiler.parameter("color_space", (compress_as_srgb) ? "sRGB" : "linear"); compiler.parameter(this, "interpolation"); compiler.parameter("is_float", is_float); compiler.parameter("use_alpha", !alpha_out->links.empty()); @@ -1467,7 +1475,7 @@ PointDensityTextureNode::~PointDensityTextureNode() { if (image_manager) { image_manager->remove_image( - filename.string(), builtin_data, interpolation, EXTENSION_CLIP, true); + filename.string(), builtin_data, interpolation, EXTENSION_CLIP, true, ustring()); } } @@ -1491,8 +1499,15 @@ void PointDensityTextureNode::add_image() { if (slot == -1) { ImageMetaData metadata; - slot = image_manager->add_image( - filename.string(), builtin_data, false, 0, interpolation, EXTENSION_CLIP, true, metadata); + slot = image_manager->add_image(filename.string(), + builtin_data, + false, + 0, + interpolation, + EXTENSION_CLIP, + true, + u_colorspace_raw, + metadata); } } @@ -1551,7 +1566,7 @@ void PointDensityTextureNode::compile(OSLCompiler &compiler) if (use_density || use_color) { add_image(); - compiler.parameter_texture("filename", ustring(), slot); + compiler.parameter_texture("filename", slot); if (space == NODE_TEX_VOXEL_SPACE_WORLD) { compiler.parameter("mapping", tfm); compiler.parameter("use_mapping", 1); |