Artifact in the limit between textures

I am trying to draw a texture that changes its scale with distance. However, the following GLSL code (fragment shader) produces an artifact:

if(dist < 800) factor = 100;
else factor = 1000;
return getTexture(factor);

The output is shown below. The artifact appears as a line between the two textures.

However, the following code doesn’t produce that artifact (unfortunately, this is not the code I need):

factor1 = 100;
factor2 = 1000;
vec3 tex1 = getTexture(factor1);
vec3 tex2 = getTexture(factor2);
float ratio = floor(dist / 800);
return ratio * tex2 + (1-ratio) * tex1;

Output:

Assuming getTexture() samples from different textures depending on its argument and dist is not dynamically uniform the implicit derivatives needed for mipmap level selection are undefined, see this wiki page for details.

About the elements from the example code:

  • getTexture() samples from the same texture. The argument passed to it just modifies the coordinates to lookup in the texture (final coordinates = coordinates / factor).
  • dist is a value received from the vertex shader that gives the distance between fragment and camera.

Purpose of the shader: To show the texture with a certain resolution/scale which depends upon the distance between fragment and camera (i.e., coordinates sampled from the texture depend upon the distance). For example, this way, if 0 < dist < 10, the texture is sampled with scale A; if 10 < dist < 20, texture is sampled with scale B; and so on.

Thanks for the link, it was helpful for understanding the issue. However, I still cannot see how to solve this. I only see 3 options:

  • Not using mipmaps (I think this would introduce worse artifacts)
  • Sample from the texture first as many times as resolutions/scales exist (not feasible since there would be a lot of texture samplings, which might be too much work for the fragment shader)
  • Use dFdx() and dFdy() (I don’t really understand these functions and whether they could help in this case).

I have seen the example pieces of code in the link that fix something similar, but it seems not to work in this case because the texture sample here may vary from one fragment to another (i.e. depending upon the distance, I take one sampling coordinates or other), they are not always the same for each fragment.