Я создаю программу, в которой я могу преобразовывать черно-белые изображения в ландшафт.
У меня есть рабочий код, но поскольку Unity имеет ограничение на количество вершин, которое может быть у меня sh Код не работает для больших изображений.
Итак, я попытался разделить изображение на меньшие изображения и создать себе sh для каждой части. это работает, но я получаю странный интервал между моими сетками, и я не уверен, почему.
Код:
public static class MeshGenerator
{
private static Transform CreateGameObjectWithMesh(Mesh m)
{
var go = new GameObject();
go.AddComponent<MeshFilter>().mesh = m;
go.AddComponent<MeshRenderer>();
m.RecalculateNormals();
return go.transform;
}
public static void Generate(float[,] heightsData)
{
int width = heightsData.GetLength(0);
int height = heightsData.GetLength(1);
float topLeftX = (width - 1) / -2f;
float topLeftZ = (height - 1) / 2f;
// Just for testing, I am working with 256X256 texture and split it to 4 parts. (would be modified when working)
for (int i = 0; i < 4; i++)
{
var startX = (i % 2) * 128;
var startY = i < 2 ? 0 : 128;
StartMeshCreationThread(mesh =>
{
var t = CreateGameObjectWithMesh(mesh);
t.position = new Vector3(topLeftX + startX + 128f / 2f, 0, topLeftZ - startY - 128f / 2f);
}, startX, startY, 128, 128, heightsData,
new Vector2(topLeftX, topLeftZ), (x, y) => new Vector2(x / (float) width, y / (float) height));
}
}
// Would create a new thread in the future.
private static void StartMeshCreationThread(Action<Mesh> onFinishedCallback, int startX, int startY, int width,
int height, float[,] heightsData, Vector2 orgTopLeft, Func<int, int, Vector2> getUVPosition)
{
var meshData = new MeshData (width, height);
float topLeftX = (width - 1) / -2f;
float topLeftZ = (height - 1) / 2f;
int vertexIndex = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
var vertexPosition = new Vector3(topLeftX + x, heightsData[x + startX, y + startY] * 10f, topLeftZ - y);
meshData.AddVertexData(vertexIndex, vertexPosition, getUVPosition(x + startX, y + startY));
if (x < width - 1 && y < height - 1)
{
meshData.AddTriangle (vertexIndex, vertexIndex + width + 1, vertexIndex + width);
meshData.AddTriangle (vertexIndex + width + 1, vertexIndex, vertexIndex + 1);
}
vertexIndex++;
}
}
onFinishedCallback(meshData.CreateMesh());
}
private class MeshData
{
private readonly Vector3[] vertices;
private readonly Vector2[] uvs;
private readonly int[] triangles;
private int triangleIndex;
public MeshData(int width, int height)
{
vertices = new Vector3[width * height];
uvs = new Vector2[width * height];
triangles = new int[(width - 1) * (height - 1) * 6];
triangleIndex = 0;
}
public void AddVertexData(int index, Vector3 vertexPosition, Vector2 uvPosition)
{
vertices[index] = vertexPosition;
uvs[index] = uvPosition;
}
public void AddTriangle(int v1, int v2, int v3)
{
triangles[triangleIndex + 0] = v1;
triangles[triangleIndex + 1] = v2;
triangles[triangleIndex + 2] = v3;
triangleIndex += 3;
}
public Mesh CreateMesh()
{
var mesh = new Mesh {vertices = vertices, triangles = triangles, uv = uvs};
return mesh;
}
}
}
Результат (для 256X256) текстура:
( основной источник )