diff --git a/internal/graphics/shader.go b/internal/graphics/shader.go index 7bb183edd..97b7d8e70 100644 --- a/internal/graphics/shader.go +++ b/internal/graphics/shader.go @@ -51,12 +51,19 @@ varying vec2 varying_tex_coord; varying vec2 varying_tex_coord_min; varying vec2 varying_tex_coord_max; +const float minHighpValue = 1.0 / 32768.0; + void main(void) { varying_tex_coord = vec2(tex_coord[0], tex_coord[1]); - varying_tex_coord_min = - vec2(min(tex_coord[0], tex_coord[2]), min(tex_coord[1], tex_coord[3])); - varying_tex_coord_max = - vec2(max(tex_coord[0], tex_coord[2]), max(tex_coord[1], tex_coord[3])); + // varying_tex_coord_min and varying_tex_coord_max mean endmost texel values + // in the source rect. As varying_tex_coord is adjusted with minHighpValue + // in vertices.go, re-adjust them so that exact endmost texel values. + varying_tex_coord_min = vec2( + min(tex_coord[0], tex_coord[2]) - minHighpValue, + min(tex_coord[1], tex_coord[3]) - minHighpValue); + varying_tex_coord_max = vec2( + max(tex_coord[0], tex_coord[2]) + minHighpValue, + max(tex_coord[1], tex_coord[3]) + minHighpValue); gl_Position = projection_matrix * vec4(vertex, 0, 1); } ` diff --git a/vertices.go b/vertices.go index b02f72047..8635d1d82 100644 --- a/vertices.go +++ b/vertices.go @@ -87,6 +87,15 @@ func vertices(sx0, sy0, sx1, sy1 int, width, height int, geo *affine.GeoM) []flo hf := float32(h) u0, v0, u1, v1 := float32(sx0)/wf, float32(sy0)/hf, float32(sx1)/wf, float32(sy1)/hf + // Adjust texels to be slightly inside the source rect. Without this + // adjustment, texels can be exactly as same values as the edges' + // positions and it could happen that nothing is rendered. (#491) + const minHighpValue = 1.0/32768.0 + u0 += minHighpValue + v0 += minHighpValue + u1 -= minHighpValue + v1 -= minHighpValue + x, y := geo.Apply32(x0, y0) // Vertex coordinates vs[0] = x