Текстурные UV-координаты не выстраиваются в линию, как ожидалось в Unity3D

Я программно создаю сетку в 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 ();
}

Обе версии кода вызывают одну и ту же проблему.


person Justin808    schedule 28.02.2016    source источник
comment
что там с бизнесом .125? Разве это не было бы 1,1 и т.д .. все 1/0 ??   -  person Fattie    schedule 29.02.2016
comment
@JoeBlow - Это не полный размер изображения. На данный момент у меня есть только одна плитка, но будет намного больше: трава, грязь, вода и т. Д. Я просто пытаюсь выровнять текстуры в данный момент.   -  person Justin808    schedule 29.02.2016
comment
хорошо - просто предложение: просто сделайте обычный квад в единстве (т.е. используйте меню). поместите на него свою текстуру. дурите со значениями, пока они не станут такими, как вы хотите. Абсолютно проверьте, что это выглядит правильно НА СЕТИ, ПРЕДОСТАВЛЕННОЙ UNITY!   -  person Fattie    schedule 29.02.2016
comment
Я пытаюсь создать мозаичную карту на одной сетке. Сетка - это не просто плоскость, поэтому я не могу использовать поставляемую сетку. Если поможет, выложу свой код.   -  person Justin808    schedule 29.02.2016
comment
ты погуглил эти неубедительные идеи? forum.unity3d.com/threads /   -  person Fattie    schedule 29.02.2016
comment
@JoeBlow - Я пробовал квадроцикл и вижу ту же белую линию.   -  person Justin808    schedule 29.02.2016
comment
привет @ justin808! Вы когда-нибудь решали это, мне было бы интересно узнать   -  person Fattie    schedule 16.07.2016


Ответы (3)


Чувак, ты нормальный, в порядке?

Они все должны прямо указывать на эту работу, верно?

Если вы используете какой-то обычный расчет по умолчанию, может быть, они пытаются аккуратно обернуть край, думая, что это куб?

person Fattie    schedule 29.02.2016
comment
Я пробовал оба способа, все указывает вверх и использует сборку в RecalculateNormals - person Justin808; 29.02.2016
comment
о, не используйте Recalc. нормали. вы на 1000% уверены, что ваши нормали верны ?? - person Fattie; 29.02.2016
comment
Вы полностью уверены, что он не работает над вами и делает RecalculateStupidNormals самостоятельно? в какой-то момент он сделает это за вас автоматически. сводит людей с ума - person Fattie; 29.02.2016
comment
Я на 99% уверен, что это ваши нормальные люди. Для проверки: просто увеличьте масштаб и посмотрите, пытается ли Unity сделать красивую гладкую грань. Распечатайте с отладкой или чем-то еще фактические окончательные нормали (не верьте, что вы установили их так, как хотите) - person Fattie; 29.02.2016

Попробуйте установить формат Truecolor. Может случиться так, что из-за сжатия границы между разными текстурами больше не резкие, а размытые, из-за чего они переходят друг в друга.

person Thomas Hilbert    schedule 29.02.2016

У меня аналогичная проблема, нет фильтра (точки) нет, на самом деле нет фильтра, за фильтром есть встроенный фильтр единства ближайшего соседа

для решения вашей проблемы вы должны разделить вашу текстуру на 4 разделенных текстуры таким образом создать 4 новых текстуры2D () сохранить все пиксели исходной текстуры в 2D-массиве методом get pixel https://docs.unity3d.com/ScriptReference/Texture2D.GetPixel.html и создайте 4 новые текстуры и используйте 4 цикла for, чтобы получить четверть исходных пикселей текстуры и установите для пикселей одну из целевых текстур https://docs.unity3d.com/ScriptReference/Texture2D.SetPixel.html https://docs.unity3d.com/ScriptReference/Texture2D.SetPixel.html

person ehsan wwe    schedule 10.12.2019