Как мне лучше написать это процедурное UV-отображение для сгенерированных шестиугольников? - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь настроить процедурное UV-картирование для динамически генерируемых сеток, но в данный момент мне не везет. У меня есть текстура 1024x1024, с плитками размером 256x, что составляет 4 столбца и 4 строки на текстуру. В настоящее время я работаю с шестиугольниками и бью несколько камней преткновения.

Когда система работает ... она генерирует это:

enter image description here

Файл текстурного атласа, о котором идет речь, это система координат, основанная на значениях от 0 до 1 и 0,0, расположенная в левом нижнем углу:

enter image description here

Это должен быть сплошной зеленый шестиугольник. Все выложено внутри циклов и должно соответствовать вершинам, но это не работает, и я не могу понять, что именно здесь происходит. Есть ли лучший способ или более эффективный метод, который бы правильно расположил uv и масштаб, чтобы соответствовать шестиугольникам в текстуре? Код, который у меня есть, приведен ниже. В первую очередь он использует списки вместо массивов для размещения дополнительных структур.

using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class HexMesh: MonoBehaviour {

    Mesh hexMesh;
    MeshCollider meshCollider;
    public List<Vector3> vertices;
    public List<Vector2> uvs;
    List<int> triangles;

    int uvRows = 4;
    int uvCols = 4;
    float uvRadius;

    public Vector2 uvDefault;

    void Awake()
    {
        uvRadius = 1.0f / uvCols / 2.0f;
        uvDefault = new Vector2(uvRadius, uvRadius);
        GetComponent<MeshFilter>().mesh = hexMesh = new Mesh();
        meshCollider = gameObject.AddComponent<MeshCollider>();
        hexMesh.name = "Hex Mesh";
        vertices = new List<Vector3>();
        uvs = new List<Vector2>();
        triangles = new List<int>();
    }

    public void Triangulate(HexCell[] cells)
    {
        hexMesh.Clear();
        vertices.Clear();
        triangles.Clear();
        uvs.Clear();
        for (int i = 0; i < cells.Length; i++)
        {
            Triangulate(cells[i]);
        }

        hexMesh.vertices = vertices.ToArray();
        hexMesh.triangles = triangles.ToArray();

        hexMesh.uv = uvs.ToArray();
        meshCollider.sharedMesh = hexMesh;
        hexMesh.RecalculateNormals();
    }

    void Triangulate(HexCell cell)
    {
        Vector3 center = cell.transform.localPosition;
        addHex(center);
    }

    void addHex(Vector3 hexCenter)
    {
        int vertexIndex = vertices.Count;

        Vector2[] uvVerts = new Vector2[6];


        Vector3 v = Vector3.forward;
        for (var k = 0; k < HexMetrics.corners.Length; k++)
        {
            vertices.Add(v * HexMetrics.outerRadius);
            Vector3 uv = v * HexMetrics.outerRadius;
            uvVerts[k] = new Vector2(uv.x, uv.z);
            v = Quaternion.AngleAxis(60.0f, Vector3.up) * v;
        }

        triangles.Add(vertexIndex);
        triangles.Add(vertexIndex + 1);
        triangles.Add(vertexIndex + 5);

        triangles.Add(vertexIndex + 5);
        triangles.Add(vertexIndex + 1);
        triangles.Add(vertexIndex + 4);

        triangles.Add(vertexIndex + 4);
        triangles.Add(vertexIndex + 1);
        triangles.Add(vertexIndex + 2);

        triangles.Add(vertexIndex + 2);
        triangles.Add(vertexIndex + 3);
        triangles.Add(vertexIndex + 4);

        for (int j = 0; j < 6; j++)
        {
            uvs.Add(uvVerts[j] + uvDefault);
        }
    }
}

1 Ответ

0 голосов
/ 20 января 2019

С помощью второго взгляда мы выяснили, в чем проблема - по крайней мере, из двух частей.Первая была в коде:

Vector3 uv = v * HexMetrics.outerRadius;
uvVerts[k] = new Vector2(uv.x, uv.z);

должно быть

uvVerts[k] = new Vector2(v.x, v.z) * uvRadius;

Вторая проблема заключалась в том, что тайлинг шейдера был полностью отключен, до 0,0, когда он должен иметьбыл 1,1.

...