UV mapping on procedural mesh isn't pixel perfect

I recently made a cube out of a procedural mesh so I could use the UV mapping for some textures. I got it working almost perfectly, but when testing using colors for each face I can tell it’s not pixel perfect.

Script
using UnityEngine;
using System.Collections;

public class CustomMeshes : MonoBehaviour
{
    #region Cube
    public static GameObject CreateCube()
    {
        GameObject gameObject = new GameObject();                   //Create GameObject to store everything
        gameObject.name = "Cube";                                   //Assign name
        gameObject.tag = "BuildingBlock";                           //Assign tag
        gameObject.layer = 11;                                      //Assign layer
        MeshFilter filter = gameObject.AddComponent<MeshFilter>();  //Add filter
        Mesh mesh = filter.mesh;                                    //Add variable to store mesh
        mesh.Clear();                                               //Clear variable of mesh
        gameObject.AddComponent<MeshRenderer>();                    //Add renderer so it's visible
        MeshCollider collider = gameObject.AddComponent<MeshCollider>();    //Add collider so it can get hit by raycasts
        

        float length = 1f;
        float width = 1f;
        float height = 1f;

        #region Vertices
        Vector3 p0 = new Vector3(-length * 0.5f, -width * 0.5f, height * 0.5f);
        Vector3 p1 = new Vector3(length * 0.5f, -width * 0.5f, height * 0.5f);
        Vector3 p2 = new Vector3(length * 0.5f, -width * 0.5f, -height * 0.5f);
        Vector3 p3 = new Vector3(-length * 0.5f, -width * 0.5f, -height * 0.5f);

        Vector3 p4 = new Vector3(-length * 0.5f, width * 0.5f, height * 0.5f);
        Vector3 p5 = new Vector3(length * 0.5f, width * 0.5f, height * 0.5f);
        Vector3 p6 = new Vector3(length * 0.5f, width * 0.5f, -height * 0.5f);
        Vector3 p7 = new Vector3(-length * 0.5f, width * 0.5f, -height * 0.5f);

        Vector3[] Vertices = new Vector3[]
        {
            //Bottom
            p0, p1, p2, p3,

            //Left
            p7, p4, p0, p3,

            //Front
            p4, p5, p1, p0,

            //Back
            p6, p7, p3, p2,

            //Right
            p5, p6, p2, p1,

            //Top
            p7, p6, p5, p4,
        };
        #endregion

        #region Normals
        Vector3 Up = Vector3.up;
        Vector3 Down = Vector3.down;
        Vector3 Front = Vector3.forward;
        Vector3 Back = Vector3.back;
        Vector3 Left = Vector3.left;
        Vector3 Right = Vector3.right;

        Vector3[] normals = new Vector3[]
        {
            //Bottom
            Down, Down, Down, Down,

            //Left 
            Left, Left, Left, Left,

            //Front
            Front, Front, Front, Front,

            //Back
            Back, Back, Back, Back,

            //Right
            Right, Right, Right, Right,

            //Top
            Up, Up, Up, Up,
        };
        #endregion

        #region UVs

        /* Assign Order
         * ----------------------
         * Bottom: Bottom left, bottom right, top right, top left.
         * Left: Top right, top left, bottom left, bottom right.
         * Front: Top right, top left, bottom left, bottom right.
         * Back: Top right, top left, bottom left, bottom right.
         * Right: Top right, top left, bottom left, bottom right.
         * Top: Bottom left, bottom right, top right, top left.
         * 
         * UV Texture Order
         * ----------------------
         * Front, Back, Top,
         * Bottom, Left, Right.
         */

        Vector2[] UVs = new Vector2[]
        {
            //Bottom
            new Vector2(0, 0), new Vector2(0.333f, 0), new Vector2(0.333f, 0.5f), new Vector2(0, 0.5f),

            //Left
            new Vector2(0.665f, 0.5f), new Vector2(0.333f, 0.5f), new Vector2(0.333f, 0), new Vector2(0.665f, 0), 

            //Front
            new Vector2(0.333f, 1), new Vector2(0, 1), new Vector2(0, 0.5f), new Vector2(0.333f, 0.5f),

            //Back
            new Vector2(0.665f, 1), new Vector2(0.333f, 1), new Vector2(0.333f, 0.5f), new Vector2(0.665f, 0.5f),

            //Right
            new Vector2(1, 0.5f), new Vector2(0.665f, 0.5f), new Vector2(0.665f, 0), new Vector2(1, 0),

            //Top
            new Vector2(0.665f, 0.5f), new Vector2(1, 0.5f), new Vector2(1, 1), new Vector2(0.665f, 1),
        };
        #endregion

        #region Triangles
        int[] triangles = new int[]
        {
            //Bottom
            3, 1, 0,
            3, 2, 1,

            //Left 
            3 + 4 * 1,      1 + 4 * 1,      0 + 4 * 1,
            3 + 4 * 1,      2 + 4 * 1,      1 + 4 * 1,  

            //Front
            3 + 4 * 2,      1 + 4 * 2,      0 + 4 * 2,
            3 + 4 * 2,      2 + 4 * 2,      1 + 4 * 2,

            //Back 
            3 + 4 * 3,      1 + 4 * 3,      0 + 4 * 3,
            3 + 4 * 3,      2 + 4 * 3,      1 + 4 * 3,

            //Right
            3 + 4 * 4,      1 + 4 * 4,      0 + 4 * 4,
            3 + 4 * 4,      2 + 4 * 4,      1 + 4 * 4,

            //Top
            3 + 4 * 5,      1 + 4 * 5,      0 + 4 * 5,
            3 + 4 * 5,      2 + 4 * 5,      1 + 4 * 5,
        };
        #endregion

        mesh.vertices = Vertices;
        mesh.normals = normals;
        mesh.uv = UVs;
        mesh.triangles = triangles;

        mesh.RecalculateBounds();
        mesh.Optimize();

        collider.sharedMesh = null;
        collider.sharedMesh = mesh;

        return gameObject;
    }
    #endregion
}

Sorry it isn’t all commented, as you might imagine it’s a work in progress. I’m sure you get the picture.

The Texture

25114-uv_testfaces_color.png

The Result

It’s not crucial since you probably won’t be able to notice once I throw on a proper texture, but it’d be neat to know it’s pixel perfect. Thanks in advance :slight_smile:

That’s how it’s suppose to work. The system doesn’t know that your texture is really 6 totally different ones. It thinks the texture is one continuous pattern.

As the cube moves and takes up different amounts of pixels, the graphic card builds it by blending in surrounding pixels. If it didn’t, there would be a funny little line along the edge. Of course, you want a sharp line along all edges, but it doesn’t know that.

You can turn off blending, with Point Filter mode, on the texture. That can give a pixelated look. The EdgePadding answer above says, “OK, let it blend in surrounding pixels, I’ll make a fence of fake ones.” Like the part of the game map you can’t walk on, and is only there so the world looks infinite.

http://wiki.polycount.com/EdgePadding