- Home /
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
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 :)
I noticed that the values that point to two thirds of the texture have 0.665 ins$$anonymous$$d of 0.666. I fixed that, which surprisingly did make a different, but it's still not optimal.
floating point precision is part of the deeper issue your running into
Answer by Owen-Reynolds · Apr 12, 2014 at 10:30 PM
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.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
UV Mapping: extra pixels either side 1 Answer
An OS design issue: File types associated with their appropriate programs 1 Answer
mesh.uv question 1 Answer