Weird Texturing Issue, Voxel Terrian Gen

Hi ive been working on a Voxel terrian generator for some time now and its nearing the end of it all, bit ive come across something weird and not entirely sure how to fix it as you can see by the image below am getting seams between each voxel, each voxel is 1x1x1 and placed right next to each other, I know it has something to do with my Atlas am using and ive played with it for hours but to no result, so am here to ask for help…

– Current Results




–My Atlas Function

    public Texture2D CreateAtlas()
    {
        string[] _Images = System.IO.Directory.GetFiles("Textures/");
        //Debug.Log("Loaded " + (_Images.Length - 1) + " Textures");

        int pixelwidth = 128;
        int pixelheight = 128;
        int AtlasWidth = Mathf.CeilToInt((Mathf.Sqrt(_Images.Length) + 2) * pixelwidth);
        int AtlasHeight = Mathf.CeilToInt((Mathf.Sqrt(_Images.Length) + 2) * pixelheight);
        //Debug.Log(AtlasWidth + "," + AtlasHeight);
        Texture2D Atlas = new Texture2D(AtlasWidth, AtlasHeight);
        int count = 0;
        for (int x = 0; x < AtlasWidth / pixelwidth; x++)
        {
            for (int y = 0; y < AtlasHeight / pixelheight; y++)
            {
                if (count >= _Images.Length - 1)
                {
                    goto end;
                }
                Texture2D temp = new Texture2D(0, 0);
                temp.LoadImage(System.IO.File.ReadAllBytes(_Images[count]));
                Atlas.SetPixels(x * pixelwidth, y * pixelheight, pixelwidth, pixelheight, temp.GetPixels());

                float startx = x * pixelwidth;
                float starty = y * pixelheight;
                float perpixelratiox = 1 / (float)Atlas.width;
                float perpixelratioy = 1 / (float)Atlas.height;
                startx *= perpixelratiox;
                starty *= perpixelratioy;
                float endx = startx + (perpixelratiox * pixelwidth);
                float endy = starty + (perpixelratioy * pixelheight);

                UVMap.AddNewMap(_Images[count], new Vector2[]
                {
                    new Vector2(startx,starty),
                    new Vector2(startx,endy),
                    new Vector2(endx,starty),
                    new Vector2(endx,endy)
                });
                count++;
            }
        }

        end:;

        Texture2D SavedAtlas = new Texture2D(0, 0);
        SavedAtlas.LoadImage(Atlas.EncodeToPNG());
        SavedAtlas.wrapMode = TextureWrapMode.Clamp;
        SavedAtlas.filterMode = FilterMode.Point;

        return SavedAtlas;
    }

–The way i setup each Voxel Cube

    private MeshData GetMeshData(Vector3 Pos, int Dir, int CurrentVertCount,Vector2[] UVMap)
    {
        List<Vector3> vertices = new List<Vector3>();
        if (Dir == 0) // Top
        {
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 1, Pos.z + 1));
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 1, Pos.z + 1));
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 1, Pos.z + 0));
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 1, Pos.z + 0));
        }

        if (Dir == 1) // Bottom
        {
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 0, Pos.z + 0));
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 0, Pos.z + 0));
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 0, Pos.z + 1));
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 0, Pos.z + 1));
        }

        if (Dir == 2) //Back
        {
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 0, Pos.z + 0));
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 0, Pos.z + 0));
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 1, Pos.z + 0));
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 1, Pos.z + 0));
        }

        if (Dir == 3) //Front
        {
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 0, Pos.z + 1));
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 0, Pos.z + 1));
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 1, Pos.z + 1));
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 1, Pos.z + 1));
        }

        if (Dir == 4) //Right
        {
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 0, Pos.z + 1));
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 0, Pos.z + 0));
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 1, Pos.z + 0));
            vertices.Add(new Vector3(Pos.x + 1, Pos.y + 1, Pos.z + 1));
        }

        if (Dir == 5) //Left
        {
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 0, Pos.z + 0));
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 0, Pos.z + 1));
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 1, Pos.z + 1));
            vertices.Add(new Vector3(Pos.x + 0, Pos.y + 1, Pos.z + 0));
        }

        List<int> Tris = new List<int>
        {
            CurrentVertCount + 0,
            CurrentVertCount + 1,
            CurrentVertCount + 3,
            CurrentVertCount + 1,
            CurrentVertCount + 2,
            CurrentVertCount + 3
        };

        List<Vector2> Uvs = new List<Vector2>
        {
            UVMap[2],UVMap[0],UVMap[1],UVMap[3]
        };

        MeshData NewData = new MeshData();
        NewData.Verts = vertices;
        NewData.Tris = Tris;
        NewData.UV = Uvs;
        return NewData;
    }

–and the atlas it create

And yes i know its minecraft, but its all the textures i had on hand XD

Ive tried turning off AA, changed anisotropic Textures all the stuff its said on Google… am just completly outta ideas now…

I did encounter this problem before. As far i know, even without anisotropic filters, unity still get some pixels from the neighbors textures, so in your picture, i think it is taking a texture with alpha 0 that is next to the ground texture, the further the model is, the bigger this problem get.

I found two solutions for this. the first one is to zoom the UV a little bit for each texture, this some times break the seamless textures.

The other one is to extend each texture in the atlas, to have extra pixels in each corner.

I do have a script that does both of those things:

I will send you a voucher for it, so you can see if any of those solutions work for you.