2
\$\begingroup\$

The following code maps the texture from a texture atlas to a UV. The problem is I'm having texture tearing issues.

Does anyone know how to overcome this problem and have any suggestions? Here is the code I have, all images are point filtered and no mipmapping is used.

    for (int i = 0; i < mesh.uv.Length; i++)
    {
        UVs.Add(GetUVTextureFromAtlas(mesh.uv[i].x, mesh.uv[i].y, voxel, 0));
    }

    [...]

    Vector2 GetUVTextureFromAtlas(float x, float y, ushort voxel, Facing side)
    {
        Rect rect = GetVoxelTextureRect(voxel, side);
        float xout = UVLerp(rect.x, rect.x + rect.width, x);
        float yout = UVLerp(rect.y, rect.y + rect.height, y); 
        return new Vector2(xout, yout);
    }
    float UVLerp(float from, float to, float t)
    {
        float difference = to - from;
        return from + (difference * t);
    }

Texture tearing apart

\$\endgroup\$
  • \$\begingroup\$ Can you describe what you mean by "texture ripping"? Usually I see that term used to mean using tools to extract texture assets from a published game. Maybe include a picture of the artifacts you're seeing, compared to your intended result? Including the definition of GetVoxelTextureRect would also help, so we can see whether it is insetting the rectangles or allowing padding between textures. \$\endgroup\$ – DMGregory Nov 4 '15 at 3:33
  • \$\begingroup\$ Sorry I meant tearing. I've updated with an image for reference. \$\endgroup\$ – Euthyphro Nov 5 '15 at 4:39
1
\$\begingroup\$

If you want to avoid bleeding issues with texture atlases, you'll have to leave gaps of at least 1 pixel between the elements in your atlas. Best practice is to use 2 pixel wide gaps and repeat the colors of the neighboring element pixels in those gaps.

But be careful with compression algorithms on your textures (e.g. when building to iOS, the compression is really agressive). They might require wider gaps to avoid compression artefacts bleeding over between sprites.

\$\endgroup\$
  • \$\begingroup\$ Question has been updated. The problem isn't bleeding, the problem is rounding where it is getting zero alpha pixels outside of the texture. I suspect the solution is to do some sort of nearest neighbour pixel calculation but j/w if anyone had a snippit of code. \$\endgroup\$ – Euthyphro Nov 3 '15 at 16:16
  • \$\begingroup\$ But none of your code does any rounding. And afaik there shouldn't be happening any rounding under the hood. I've encountered similar issues with point-fitered 2d sprites (which are implemented as quads in unity) and picel snapped uv-coordinates. I'm certain those issues were caused by floating point inaccuracy. The best workaroud for me was to add bleed zones to my sprites/texture elements. I know you are not working with 2d sprites, but the underlying principles are the same. Take a look here \$\endgroup\$ – pLaw Nov 3 '15 at 16:44
  • \$\begingroup\$ In fact, getting the nearest pixel would require the rounding of the values xout and yout in your code. \$\endgroup\$ – pLaw Nov 3 '15 at 16:51
  • \$\begingroup\$ Will this not create issues then for seamless textures? If you're having to add bleed zone, if your texture is seamless you will then have non-seamless textures. \$\endgroup\$ – Euthyphro Nov 3 '15 at 16:53
  • \$\begingroup\$ That shouldn't have any effect on seamless textures. If you use sprites within an atlas that have to be seamless, you will have to make sure the sprite in question is seamless, regardless of having a bleed zone or not. The bleed zone is outside of your sprite and ensures, inaccuracies in the uv coordinates do not cause gaps. Actually, adding a bleed zone is a technique to ensure seamlessness of sprites. \$\endgroup\$ – pLaw Nov 3 '15 at 17:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.