- Home /
Remove Distortion on custom UV mesh
I've been able to create UVs for my custom meshes but when I put a texture on them they distort in some places. Is there a way to remove this distortion?
This is my code to generate the Uvs:
Mesh mesh = meshFilter.sharedMesh;
Vector3[] vertices = mesh.vertices;
//Separate the components of the verticies to find the size of mesh
List<Vector3> Ver = new List<Vector3>(vertices);
List<float> Xes = new List<float>();
List<float> Zes = new List<float>();
foreach(Vector3 v in Ver)
{
Xes.Add(v.x);
Zes.Add(v.z);
}
Xes.Sort();
Zes.Sort();
float Height = Mathf.Abs(Zes[0] - Zes[Zes.Count - 1]);
float Width = Mathf.Abs(Xes[0] - Xes[Xes.Count - 1]);
Vector2[] uvs = new Vector2[vertices.Length];
for (int i = 0; i < uvs.Length; i++)
{
uvs[i] = new Vector2(Mathf.Abs(vertices[i].x/Width), Mathf.Abs(vertices[i].z/Height));
}
Vects = vertices;
UVA = uvs;
mesh.uv = uvs;
Answer by Bunny83 · Sep 07, 2018 at 05:39 AM
Using "abs" makes not really sense here. You calculate the whole range between the min and max positions. However if min is negative you do a strange folding on the negative values. For example imagine X min is -2 and X max is 18. That gives a range of "20". You take the absolute value of the actual x value and divide by 20. Since no x value is actually 20 you never get a value of 1. Due to the absolute value you just flip the negative part into the positive.
There are several things you should change. First of all to get the min and max values, don't use two seperate lists that's just a waste of memory and processing time.
Second you have to subtract the min value from the actual coordinate before you divide by the range.
Vector3[] vertices = mesh.vertices;
Vector3 min = Vector3.one * float.PositiveInfinity;
Vector3 max = Vector3.one * float.NegativeInfinity;
foreach(Vector3 v in vertices)
{
if (v.x > max.x) max.x = v.x;
if (v.y > max.y) max.y = v.y;
if (v.z > max.z) max.z = v.z;
if (v.x < min.x) min.x = v.x;
if (v.y < min.y) min.y = v.y;
if (v.z < min.z) min.z = v.z;
}
Vector3 size = max - min;
Vector2[] uvs = new Vector2[vertices.Length];
for (int i = 0; i < uvs.Length; i++)
{
Vector3 v = vertices[i] - min;
uvs[i] = new Vector2(v.x / size.x, v.z / size.z);
}
mesh.uv = uvs;
Your answer
Follow this Question
Related Questions
Substance Material UV tiling 1 Answer
Trouble with UV Mapping 1 Answer
UV Mapping: extra pixels either side 1 Answer
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers