Я программно создаю сетку в Unity3D. Каждая секция сетки состоит из 4-х вершин:
// 1 ----- 2
// | a / |
// | / b |
// 3 ----- 4
Мои UV:
1 = 0, 1
2 = 0.125, 1
3 = 0, 0.875
4 = 0.125, 0.875
Моя текстура 2048x2048. Плитка находится в верхнем левом углу изображения и имеет размер 256x256. Я немного обновил текстуру, добавив несколько дополнительных плиток, чтобы лучше понять, что я пытаюсь сделать.
Я получаю белые края вокруг каждой плитки на сетке.
Я импортирую изображение со следующими настройками.
Код для создания сетки (ручные нормали):
IEnumerator BuildMesh (int width, int height, float tileSize) {
float halfSize = tileSize / 2f;
List<Vector3> vertices = new List<Vector3> ();
List<Vector3> normals = new List<Vector3> ();
List<Vector2> uv = new List<Vector2> ();
List<int> triangles = new List<int> ();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int tileVertIdx = vertices.Count;
float h = map.GetHeight(startX + x, startY + y);
float n = map.GetHeight(startX + x, startY + y - 1);
float s = map.GetHeight(startX + x, startY + y + 1);
float e = map.GetHeight(startX + x + 1, startY + y);
float w = map.GetHeight(startX + x - 1, startY + y);
float ne = map.GetHeight(startX + x + 1, startY + y - 1);
float nw = map.GetHeight(startX + x - 1, startY + y - 1);
float se = map.GetHeight(startX + x + 1, startY + y + 1);
float sw = map.GetHeight(startX + x - 1, startY + y + 1);
Vector3 tileCenter = new Vector3 (x * tileSize, h, y * tileSize);
Rect topUV = map.GetTopUV ((int)h);
if (n == h && s == h && e == h && w == h && ne == h && nw == h && se == h && sw == h) {
// Each tile
// 1 ----- 2
// | a / |
// | / b |
// 3 ----- 4
// top row
vertices.Add (new Vector3 (tileCenter.x - halfSize, tileCenter.y, tileCenter.z - halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, tileCenter.y, tileCenter.z - halfSize));
// bottom row
vertices.Add (new Vector3 (tileCenter.x - halfSize, tileCenter.y, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, tileCenter.y, tileCenter.z + halfSize));
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
uv.Add (new Vector2(topUV.x, topUV.y));
uv.Add (new Vector2(topUV.x - topUV.width, topUV.y));
uv.Add (new Vector2(topUV.x, topUV.y - topUV.height));
uv.Add (new Vector2(topUV.x - topUV.width, topUV.y - topUV.height));
// a
triangles.Add (tileVertIdx + 0);
triangles.Add (tileVertIdx + 2);
triangles.Add (tileVertIdx + 1);
// b
triangles.Add (tileVertIdx + 1);
triangles.Add (tileVertIdx + 2);
triangles.Add (tileVertIdx + 3);
} else {
// Each tile
// 1 - 2 - 3 14 --- 16
// |a\b|c/d\ | k / |
// 4 - 5 - 6 | / |
// |e/f|g\h| | / l |
// 7 - 8 - 9 15 --- 17
// 10 --- 11
// | i / j |
// 12 --- 13
// top row
vertices.Add (new Vector3 (tileCenter.x - halfSize, tileCenter.y, tileCenter.z - halfSize));
vertices.Add (new Vector3 (tileCenter.x, tileCenter.y, tileCenter.z - halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, tileCenter.y, tileCenter.z - halfSize));
// middle row
vertices.Add (new Vector3 (tileCenter.x - halfSize, tileCenter.y, tileCenter.z));
vertices.Add (new Vector3 (tileCenter.x, tileCenter.y, tileCenter.z));
vertices.Add (new Vector3 (tileCenter.x + halfSize, tileCenter.y, tileCenter.z));
// bottom row
vertices.Add (new Vector3 (tileCenter.x - halfSize, tileCenter.y, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x, tileCenter.y, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, tileCenter.y, tileCenter.z + halfSize));
// bottom square
vertices.Add (new Vector3 (tileCenter.x - halfSize, h, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, h, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x - halfSize, s, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, s, tileCenter.z + halfSize));
// right square
vertices.Add (new Vector3 (tileCenter.x + halfSize, h, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, h, tileCenter.z - halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, e, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, e, tileCenter.z - halfSize));
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
normals.Add (Vector3.up);
uv.Add (new Vector2(topUV.x, topUV.y));
uv.Add (new Vector2(topUV.x - (topUV.width / 2), topUV.y));
uv.Add (new Vector2(topUV.x - topUV.width, topUV.y));
uv.Add (new Vector2(topUV.x, topUV.y - (topUV.height / 2)));
uv.Add (new Vector2(topUV.x - (topUV.width / 2), topUV.y - (topUV.height / 2)));
uv.Add (new Vector2(topUV.x - topUV.width, topUV.y - (topUV.height / 2)));
uv.Add (new Vector2(topUV.x, topUV.y - topUV.height));
uv.Add (new Vector2(topUV.x - (topUV.width / 2), topUV.y - topUV.height));
uv.Add (new Vector2(topUV.x - topUV.width, topUV.y - topUV.height));
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
// a
triangles.Add (tileVertIdx + 0);
triangles.Add (tileVertIdx + 3);
triangles.Add (tileVertIdx + 4);
// b
triangles.Add (tileVertIdx + 0);
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 1);
// c
triangles.Add (tileVertIdx + 1);
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 2);
// d
triangles.Add (tileVertIdx + 2);
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 5);
// e
triangles.Add (tileVertIdx + 3);
triangles.Add (tileVertIdx + 6);
triangles.Add (tileVertIdx + 4);
// f
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 6);
triangles.Add (tileVertIdx + 7);
// g
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 7);
triangles.Add (tileVertIdx + 8);
// h
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 8);
triangles.Add (tileVertIdx + 5);
// i
triangles.Add (tileVertIdx + 9);
triangles.Add (tileVertIdx + 11);
triangles.Add (tileVertIdx + 10);
// j
triangles.Add (tileVertIdx + 10);
triangles.Add (tileVertIdx + 11);
triangles.Add (tileVertIdx + 12);
// k
triangles.Add (tileVertIdx + 13);
triangles.Add (tileVertIdx + 15);
triangles.Add (tileVertIdx + 14);
// l
triangles.Add (tileVertIdx + 15);
triangles.Add (tileVertIdx + 16);
triangles.Add (tileVertIdx + 14);
}
}
yield return null;
}
Mesh mesh = _meshFilter.mesh;
mesh.vertices = vertices.ToArray ();
mesh.triangles = triangles.ToArray ();
mesh.normals = normals.ToArray ();
mesh.uv = uv.ToArray ();
// mesh.RecalculateNormals ();
// mesh.Optimize ();
map.ChunkFinished ();
}
Код для создания сетки (автоматические нормали):
IEnumerator BuildMesh (int width, int height, float tileSize) {
float halfSize = tileSize / 2f;
List<Vector3> vertices = new List<Vector3> ();
List<Vector3> normals = new List<Vector3> ();
List<Vector2> uv = new List<Vector2> ();
List<int> triangles = new List<int> ();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int tileVertIdx = vertices.Count;
float h = map.GetHeight(startX + x, startY + y);
float n = map.GetHeight(startX + x, startY + y - 1);
float s = map.GetHeight(startX + x, startY + y + 1);
float e = map.GetHeight(startX + x + 1, startY + y);
float w = map.GetHeight(startX + x - 1, startY + y);
float ne = map.GetHeight(startX + x + 1, startY + y - 1);
float nw = map.GetHeight(startX + x - 1, startY + y - 1);
float se = map.GetHeight(startX + x + 1, startY + y + 1);
float sw = map.GetHeight(startX + x - 1, startY + y + 1);
Vector3 tileCenter = new Vector3 (x * tileSize, h, y * tileSize);
Rect topUV = map.GetTopUV ((int)h);
if (n == h && s == h && e == h && w == h && ne == h && nw == h && se == h && sw == h) {
// Each tile
// 1 ----- 2
// | a / |
// | / b |
// 3 ----- 4
// top row
vertices.Add (new Vector3 (tileCenter.x - halfSize, tileCenter.y, tileCenter.z - halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, tileCenter.y, tileCenter.z - halfSize));
// bottom row
vertices.Add (new Vector3 (tileCenter.x - halfSize, tileCenter.y, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, tileCenter.y, tileCenter.z + halfSize));
uv.Add (new Vector2(topUV.x, topUV.y));
uv.Add (new Vector2(topUV.x - topUV.width, topUV.y));
uv.Add (new Vector2(topUV.x, topUV.y - topUV.height));
uv.Add (new Vector2(topUV.x - topUV.width, topUV.y - topUV.height));
// a
triangles.Add (tileVertIdx + 0);
triangles.Add (tileVertIdx + 2);
triangles.Add (tileVertIdx + 1);
// b
triangles.Add (tileVertIdx + 1);
triangles.Add (tileVertIdx + 2);
triangles.Add (tileVertIdx + 3);
} else {
// Each tile
// 1 - 2 - 3 14 --- 16
// |a\b|c/d\ | k / |
// 4 - 5 - 6 | / |
// |e/f|g\h| | / l |
// 7 - 8 - 9 15 --- 17
// 10 --- 11
// | i / j |
// 12 --- 13
// top row
vertices.Add (new Vector3 (tileCenter.x - halfSize, tileCenter.y, tileCenter.z - halfSize));
vertices.Add (new Vector3 (tileCenter.x, tileCenter.y, tileCenter.z - halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, tileCenter.y, tileCenter.z - halfSize));
// middle row
vertices.Add (new Vector3 (tileCenter.x - halfSize, tileCenter.y, tileCenter.z));
vertices.Add (new Vector3 (tileCenter.x, tileCenter.y, tileCenter.z));
vertices.Add (new Vector3 (tileCenter.x + halfSize, tileCenter.y, tileCenter.z));
// bottom row
vertices.Add (new Vector3 (tileCenter.x - halfSize, tileCenter.y, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x, tileCenter.y, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, tileCenter.y, tileCenter.z + halfSize));
// bottom square
vertices.Add (new Vector3 (tileCenter.x - halfSize, h, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, h, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x - halfSize, s, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, s, tileCenter.z + halfSize));
// right square
vertices.Add (new Vector3 (tileCenter.x + halfSize, h, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, h, tileCenter.z - halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, e, tileCenter.z + halfSize));
vertices.Add (new Vector3 (tileCenter.x + halfSize, e, tileCenter.z - halfSize));
uv.Add (new Vector2(topUV.x, topUV.y));
uv.Add (new Vector2(topUV.x - (topUV.width / 2), topUV.y));
uv.Add (new Vector2(topUV.x - topUV.width, topUV.y));
uv.Add (new Vector2(topUV.x, topUV.y - (topUV.height / 2)));
uv.Add (new Vector2(topUV.x - (topUV.width / 2), topUV.y - (topUV.height / 2)));
uv.Add (new Vector2(topUV.x - topUV.width, topUV.y - (topUV.height / 2)));
uv.Add (new Vector2(topUV.x, topUV.y - topUV.height));
uv.Add (new Vector2(topUV.x - (topUV.width / 2), topUV.y - topUV.height));
uv.Add (new Vector2(topUV.x - topUV.width, topUV.y - topUV.height));
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
uv.Add (Vector2.up);
// a
triangles.Add (tileVertIdx + 0);
triangles.Add (tileVertIdx + 3);
triangles.Add (tileVertIdx + 4);
// b
triangles.Add (tileVertIdx + 0);
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 1);
// c
triangles.Add (tileVertIdx + 1);
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 2);
// d
triangles.Add (tileVertIdx + 2);
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 5);
// e
triangles.Add (tileVertIdx + 3);
triangles.Add (tileVertIdx + 6);
triangles.Add (tileVertIdx + 4);
// f
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 6);
triangles.Add (tileVertIdx + 7);
// g
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 7);
triangles.Add (tileVertIdx + 8);
// h
triangles.Add (tileVertIdx + 4);
triangles.Add (tileVertIdx + 8);
triangles.Add (tileVertIdx + 5);
// i
triangles.Add (tileVertIdx + 9);
triangles.Add (tileVertIdx + 11);
triangles.Add (tileVertIdx + 10);
// j
triangles.Add (tileVertIdx + 10);
triangles.Add (tileVertIdx + 11);
triangles.Add (tileVertIdx + 12);
// k
triangles.Add (tileVertIdx + 13);
triangles.Add (tileVertIdx + 15);
triangles.Add (tileVertIdx + 14);
// l
triangles.Add (tileVertIdx + 15);
triangles.Add (tileVertIdx + 16);
triangles.Add (tileVertIdx + 14);
}
}
yield return null;
}
Mesh mesh = _meshFilter.mesh;
mesh.vertices = vertices.ToArray ();
mesh.triangles = triangles.ToArray ();
mesh.uv = uv.ToArray ();
mesh.RecalculateNormals ();
mesh.Optimize ();
map.ChunkFinished ();
}
Обе версии кода вызывают одну и ту же проблему.