diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-06-07 18:49:58 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-06-07 21:51:40 +0300 |
commit | fb03f50e069d66c99391e4796e1b9eaa2b4cc133 (patch) | |
tree | 10c761cf548c6d4aa9160eed7c2798a96b798ccb /source/blender/draw/engines/workbench/shaders | |
parent | d05f27c7b95371db9e7e4e34a919a3623682a114 (diff) |
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.
Diffstat (limited to 'source/blender/draw/engines/workbench/shaders')
3 files changed, 10 insertions, 5 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl index 96f8f6e4c7a..59a463f49c3 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl @@ -140,7 +140,10 @@ vec2 matcap_uv_compute(vec3 I, vec3 N, bool flipped) return matcap_uv * 0.496 + 0.5; } -vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool nearest_sampling) +vec4 workbench_sample_texture(sampler2D image, + vec2 coord, + bool nearest_sampling, + bool premultiplied) { vec2 tex_size = vec2(textureSize(image, 0).xy); /* TODO(fclem) We could do the same with sampler objects. @@ -148,8 +151,8 @@ vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool nearest_sampling vec2 uv = nearest_sampling ? (floor(coord * tex_size) + 0.5) / tex_size : coord; vec4 color = texture(image, uv); - /* Unpremultiply, ideally shaders would be added so this is not needed. */ - if (!(color.a == 0.0 || color.a == 1.0)) { + /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ + if (premultiplied && !(color.a == 0.0 || color.a == 1.0)) { color.rgb = color.rgb / color.a; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl index 51bce639b63..c78b2182d04 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl @@ -2,6 +2,7 @@ uniform float ImageTransparencyCutoff = 0.1; uniform sampler2D image; uniform bool imageNearest; +uniform bool imagePremultiplied; uniform float alpha = 0.5; uniform vec2 invertedViewportSize; @@ -43,7 +44,7 @@ void main() vec4 diffuse_color; #if defined(V3D_SHADING_TEXTURE_COLOR) - diffuse_color = workbench_sample_texture(image, uv_interp, imageNearest); + diffuse_color = workbench_sample_texture(image, uv_interp, imageNearest, imagePremultiplied); if (diffuse_color.a < ImageTransparencyCutoff) { discard; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl index af9f1d14f4a..c673b2484de 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl @@ -7,6 +7,7 @@ uniform float materialRoughness; uniform sampler2D image; uniform float ImageTransparencyCutoff = 0.1; uniform bool imageNearest; +uniform bool imagePremultiplied; #ifdef NORMAL_VIEWPORT_PASS_ENABLED in vec3 normal_viewport; @@ -40,7 +41,7 @@ void main() vec4 color; # if defined(V3D_SHADING_TEXTURE_COLOR) - color = workbench_sample_texture(image, uv_interp, imageNearest); + color = workbench_sample_texture(image, uv_interp, imageNearest, imagePremultiplied); if (color.a < ImageTransparencyCutoff) { discard; } |