From 59aed2a255f22f0cf91dbdf2e9daac179b9c2649 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 22 May 2020 14:11:03 +0200 Subject: Fix T73726: Workbench Closest Interpolation Artifacts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All textures in workbench are using linear interpolation. The fragment shader modifies the uv coordinates to sample always in the center of a texel. In rare conditions the GPU could sample an incorrect value due to rounding errors making some rendering artifacts. This patch skips the interpolation in the fragment shader to remove these render artifacts. Reviewed By: Clément Foucault Differential Revision: https://developer.blender.org/D7816 --- .../workbench/shaders/workbench_image_lib.glsl | 24 ++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source/blender/draw/engines/workbench') diff --git a/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl index 6f99739f259..e45f7a7b9e3 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl @@ -24,11 +24,17 @@ bool node_tex_tile_lookup(inout vec3 co, sampler2DArray ima, sampler1DArray map) vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool nearest_sampling) { - vec2 tex_size = vec2(textureSize(image, 0).xy); /* TODO(fclem) We could do the same with sampler objects. * But this is a quick workaround instead of messing with the GPUTexture itself. */ - vec2 uv = nearest_sampling ? (floor(coord * tex_size) + 0.5) / tex_size : coord; - return texture(image, uv); + if (nearest_sampling) { + /* Use texelFetch for nearest_sampling to reduce glitches. See: T73726 */ + vec2 tex_size = vec2(textureSize(image, 0).xy); + ivec2 uv = ivec2(floor(coord * tex_size) + 0.5); + return texelFetch(image, uv, 0); + } + else { + return texture(image, coord); + } } vec4 workbench_sample_texture_array(sampler2DArray tile_array, @@ -36,7 +42,6 @@ vec4 workbench_sample_texture_array(sampler2DArray tile_array, vec2 coord, bool nearest_sampling) { - vec2 tex_size = vec2(textureSize(tile_array, 0).xy); vec3 uv = vec3(coord, 0); if (!node_tex_tile_lookup(uv, tile_array, tile_data)) @@ -44,8 +49,15 @@ vec4 workbench_sample_texture_array(sampler2DArray tile_array, /* TODO(fclem) We could do the same with sampler objects. * But this is a quick workaround instead of messing with the GPUTexture itself. */ - uv.xy = nearest_sampling ? (floor(uv.xy * tex_size) + 0.5) / tex_size : uv.xy; - return texture(tile_array, uv); + if (nearest_sampling) { + /* Use texelFetch for nearest_sampling to reduce glitches. See: T73726 */ + vec3 tex_size = vec3(textureSize(tile_array, 0)); + uv.xy = floor(uv.xy * tex_size.xy) + 0.5; + return texelFetch(tile_array, ivec3(uv), 0); + } + else { + return texture(tile_array, uv); + } } uniform sampler2DArray imageTileArray; -- cgit v1.2.3