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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-04-23 14:56:30 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-05-13 16:56:10 +0300
commit7ad802cf3ae500bc72863b6dba0f28a488fce3d1 (patch)
treea1dd8b96c21a8ba51434933163b5792564006d55 /source/blender/nodes/shader
parente9d2ec46c413718cd058abba84e2badd48542781 (diff)
Cycles/Eevee: unified and improved texture image color space handling
Cycles now uses the color space on the image datablock, and uses OpenColorIO to convert to scene linear as needed. Byte images do not take extra memory, they are compressed in scene linear + sRGB transfer function which in common cases is a no-op. Eevee and workbench were changed to work similar. Float images are stored as scene linear. Byte images are compressed as scene linear + sRGB and stored in a GL_SRGB8_ALPHA8 texture. From the GLSL shader side this means they are read as scene linear, simplifying the code and taking advantage of hardware support. Further, OpenGL image textures are now all stored with premultiplied alpha. Eevee texture sampling looks a little different now because interpolation happens premultiplied and in scene linear space. Overlays and grease pencil work in sRGB space so those now have an extra conversion to sRGB after reading from image textures. This is not particularly elegant but as long as engines use different conventions, one or the other needs to do conversion. This change breaks compatibility for cases where multiple image texture nodes were using the same image with different color space node settings. However it gives more predictable behavior for baking and texture painting if save, load and image editing operations have a single color space to handle. Differential Revision: https://developer.blender.org/D4807
Diffstat (limited to 'source/blender/nodes/shader')
-rw-r--r--source/blender/nodes/shader/node_shader_util.h1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c23
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c47
3 files changed, 25 insertions, 46 deletions
diff --git a/source/blender/nodes/shader/node_shader_util.h b/source/blender/nodes/shader/node_shader_util.h
index 916cb81953e..165ada05a56 100644
--- a/source/blender/nodes/shader/node_shader_util.h
+++ b/source/blender/nodes/shader/node_shader_util.h
@@ -67,6 +67,7 @@
#include "RE_shader_ext.h"
#include "GPU_material.h"
+#include "GPU_texture.h"
#include "GPU_uniformbuffer.h"
bool sh_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index c3b8bc8bfd0..615f55e4350 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -46,7 +46,6 @@ static void node_shader_init_tex_environment(bNodeTree *UNUSED(ntree), bNode *no
NodeTexEnvironment *tex = MEM_callocN(sizeof(NodeTexEnvironment), "NodeTexEnvironment");
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
- tex->color_space = SHD_COLORSPACE_COLOR;
tex->projection = SHD_PROJ_EQUIRECTANGULAR;
BKE_imageuser_default(&tex->iuser);
@@ -68,7 +67,6 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
NodeTexImage *tex_original = node_original->storage;
ImageUser *iuser = &tex_original->iuser;
- int isdata = tex->color_space == SHD_COLORSPACE_NONE;
GPUNodeLink *outalpha;
if (!ima) {
@@ -89,7 +87,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
"node_tex_environment_equirectangular",
in[0].link,
GPU_constant(&clamp_size),
- GPU_image(ima, iuser, isdata),
+ GPU_image(ima, iuser),
&in[0].link);
}
else {
@@ -104,7 +102,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_linear_no_mip",
in[0].link,
- GPU_image(ima, iuser, isdata),
+ GPU_image(ima, iuser),
&out[0].link,
&outalpha);
break;
@@ -112,26 +110,19 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
GPU_link(mat,
"node_tex_image_nearest",
in[0].link,
- GPU_image(ima, iuser, isdata),
+ GPU_image(ima, iuser),
&out[0].link,
&outalpha);
break;
default:
- GPU_link(mat,
- "node_tex_image_cubic",
- in[0].link,
- GPU_image(ima, iuser, isdata),
- &out[0].link,
- &outalpha);
+ GPU_link(
+ mat, "node_tex_image_cubic", in[0].link, GPU_image(ima, iuser), &out[0].link, &outalpha);
break;
}
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
- GPU_material_do_color_management(mat)) {
- GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
+ if (out[0].hasoutput) {
+ GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link);
}
- BKE_image_release_ibuf(ima, ibuf, NULL);
return true;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index 722434ce783..95e76491b4a 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -57,7 +57,6 @@ static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node)
NodeTexImage *tex = MEM_callocN(sizeof(NodeTexImage), "NodeTexImage");
BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT);
BKE_texture_colormapping_default(&tex->base.color_mapping);
- tex->color_space = SHD_COLORSPACE_COLOR;
BKE_imageuser_default(&tex->iuser);
node->storage = tex;
@@ -99,7 +98,6 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
const char *gpu_node_name = (tex->projection == SHD_PROJ_BOX) ? names_box[tex->interpolation] :
names[tex->interpolation];
- bool do_color_correction = false;
bool do_texco_extend = (tex->extension != SHD_IMAGE_EXTENSION_REPEAT);
const bool do_texco_clip = (tex->extension == SHD_IMAGE_EXTENSION_CLIP);
@@ -114,20 +112,10 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPUNodeLink *vnor, *ob_mat, *blend;
GPUNodeLink **texco = &in[0].link;
- int isdata = tex->color_space == SHD_COLORSPACE_NONE;
-
if (!ima) {
return GPU_stack_link(mat, node, "node_tex_image_empty", in, out);
}
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- if ((tex->color_space == SHD_COLORSPACE_COLOR) && ibuf &&
- (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
- GPU_material_do_color_management(mat)) {
- do_color_correction = true;
- }
- BKE_image_release_ibuf(ima, ibuf, NULL);
-
if (!*texco) {
*texco = GPU_attribute(CD_MTFACE, "");
}
@@ -140,26 +128,20 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser, isdata), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
break;
case SHD_PROJ_BOX:
vnor = GPU_builtin(GPU_WORLD_NORMAL);
ob_mat = GPU_builtin(GPU_OBJECT_MATRIX);
blend = GPU_uniform(&tex->projection_blend);
- gpu_image = GPU_image(ima, iuser, isdata);
+ gpu_image = GPU_image(ima, iuser);
/* equivalent to normal_world_to_object */
GPU_link(mat, "normal_transform_transposed_m4v3", vnor, ob_mat, &norm);
- GPU_link(
- mat, gpu_node_name, *texco, norm, GPU_image(ima, iuser, isdata), &col1, &col2, &col3);
- if (do_color_correction) {
- GPU_link(mat, "srgb_to_linearrgb", col1, &col1);
- GPU_link(mat, "srgb_to_linearrgb", col2, &col2);
- GPU_link(mat, "srgb_to_linearrgb", col3, &col3);
- }
+ GPU_link(mat, gpu_node_name, *texco, norm, GPU_image(ima, iuser), &col1, &col2, &col3);
GPU_stack_link(
mat, node, "node_tex_image_box", in, out, norm, col1, col2, col3, gpu_image, blend);
break;
@@ -171,9 +153,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser, isdata), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
break;
case SHD_PROJ_TUBE:
@@ -183,20 +165,25 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
GPU_link(mat, "set_rgb", *texco, &input_coords);
}
if (do_texco_extend) {
- GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser, isdata), texco);
+ GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco);
}
- GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata));
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser));
break;
}
if (tex->projection != SHD_PROJ_BOX) {
if (do_texco_clip) {
gpu_node_name = names_clip[tex->interpolation];
- GPU_stack_link(
- mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata), out[0].link);
+ GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser), out[0].link);
+ }
+ }
+
+ if (out[0].hasoutput) {
+ if (out[1].hasoutput) {
+ GPU_link(mat, "tex_color_alpha_unpremultiply", out[0].link, &out[0].link);
}
- if (do_color_correction) {
- GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
+ else {
+ GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link);
}
}