From fb03f50e069d66c99391e4796e1b9eaa2b4cc133 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 7 Jun 2019 17:49:58 +0200 Subject: Fix T64625: Eevee image textures with alpha have dark edges Now texture storage of images is defined by the alpha mode of the image. The downside of this is that there can be artifacts near alpha edges where pixels with zero alpha bleed in. It also adds more code complexity since image textures are no longer all stored the same way. This changes allows us to keep using sRGB texture formats, which have edge darkening when stored with premultiplied alpha. Game engines seems to generally do the same thing, and we want to be compatible with them. --- .../shader/nodes/node_shader_tex_environment.c | 15 +++++++++- .../nodes/shader/nodes/node_shader_tex_image.c | 32 ++++++++++++++++------ 2 files changed, 38 insertions(+), 9 deletions(-) (limited to 'source/blender/nodes') 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 615f55e4350..bd8355ec885 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -121,7 +121,20 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, } if (out[0].hasoutput) { - GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link); + if (ELEM(ima->alpha_mode, IMA_ALPHA_IGNORE, IMA_ALPHA_CHANNEL_PACKED) || + IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name)) { + /* Don't let alpha affect color output in these cases. */ + GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link); + } + else { + /* Always output with premultiplied alpha. */ + if (ima->alpha_mode == IMA_ALPHA_PREMUL) { + GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link); + } + else { + GPU_link(mat, "tex_color_alpha_premultiply", out[0].link, &out[0].link); + } + } } 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 786386bb63e..6f3614e357d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -180,16 +180,32 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, } if (out[0].hasoutput) { - /* When the alpha socket is used, unpremultiply alpha. This makes it so - * that if we blend the color with a transparent shader using alpha as - * a factor, we don't multiply alpha into the color twice. */ - if (out[1].hasoutput && - !(ELEM(ima->alpha_mode, IMA_ALPHA_IGNORE, IMA_ALPHA_CHANNEL_PACKED) || - IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name))) { - GPU_link(mat, "tex_color_alpha_unpremultiply", out[0].link, &out[0].link); + if (ELEM(ima->alpha_mode, IMA_ALPHA_IGNORE, IMA_ALPHA_CHANNEL_PACKED) || + IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name)) { + /* Don't let alpha affect color output in these cases. */ + GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link); } else { - GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link); + /* Output premultiplied alpha depending on alpha socket usage. This makes + * it so that if we blend the color with a transparent shader using alpha as + * a factor, we don't multiply alpha into the color twice. And if we do + * not, then there will be no artifacts from zero alpha areas. */ + if (ima->alpha_mode == IMA_ALPHA_PREMUL) { + if (out[1].hasoutput) { + GPU_link(mat, "tex_color_alpha_unpremultiply", out[0].link, &out[0].link); + } + else { + GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link); + } + } + else { + if (out[1].hasoutput) { + GPU_link(mat, "tex_color_alpha_clear", out[0].link, &out[0].link); + } + else { + GPU_link(mat, "tex_color_alpha_premultiply", out[0].link, &out[0].link); + } + } } } -- cgit v1.2.3