Странная текстура сетки, созданная кодом в Unity

Я учусь создавать сетки по коду в Unity, но текстура странная, как на картинке, кто-нибудь знает, почему это так? Я создал UV-карту, как она есть в коде, много искал в документации Google и Unity и увидел, что мне нужно использовать вершины массива для отображения UV, но я думаю, что сделал что-то не так https://i.stack  .imgur.com/F4uo8.png

Мой код:

public Vector3[] verts = {
    new Vector3(-0.5f, 0.5f, 0f), new Vector3(0.5f, 0.5f, 0f),
    new Vector3(0.5f, -0.5f, 0f), new Vector3(-0.5f, -0.5f, 0f),
    new Vector3(-0.2f, 0.3f, 0f), new Vector3(0.2f, 0.3f, 0f),
    new Vector3(0.2f, -0.1f, 0f), new Vector3(-0.2f, -0.1f, 0f),
    new Vector3(-0.2f, 0.3f, 0f), new Vector3(0.2f, 0.3f, 0f),
    new Vector3(0.2f, -0.1f, 0f), new Vector3(-0.2f, -0.1f, 0f),
    new Vector3(-0.2f, 0.3f, 0.1f), new Vector3(0.2f, 0.3f, 0.1f),
    new Vector3(0.2f, -0.1f, 0.1f), new Vector3(-0.2f, -0.1f, 0.1f),
    new Vector3(-0.2f, 0.3f, 0.1f), new Vector3(0.2f, 0.3f, 0.1f),
    new Vector3(0.2f, -0.1f, 0.1f), new Vector3(-0.2f, -0.1f, 0.1f),
    new Vector3(-0.5f, 0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(-0.5f, -0.5f, 0.1f), new Vector3(-0.5f, -0.5f, 0.1f),
    new Vector3(0.5f, 0.5f, 0.1f), new Vector3(0.5f, -0.5f, 0.1f)
 };
 public int[] tris = {
     0,1,4,1,5,4,1,2,5,2,6,5,2,3,6,3,7,6,3,0,7,0,4,7,8,9,12,9,13,12,9,10,13,10,14,13,10,11,14,11,15,14,11,8,15,8,12,15,20,0,3,20,3,21,0,20,46,0,46,1,1,46,47,1,47,2,3,2,42,2,47,45,46,20,17,20,16,17,20,19,16,20,32,15,31,14,15,31,47,14,47,46,14,46,17,14
 };

MeshFilter mF = gameObject.GetComponent<MeshFilter> ();
Mesh msh = new Mesh ();
msh.vertices = verts;
msh.triangles = tris;
Vector2[] uvs = new Vector2[verts.Length];
for (int i = 0; i < uvs.Length; i++){ //uv map
    uvs[i] = new Vector2(verts[i].x, verts[i].y);
 }
 msh.uv = uvs;
 msh.RecalculateNormals ();
 mF.mesh = msh;

person victor oliveira    schedule 22.12.2019    source источник


Ответы (2)


Поскольку вы уже обнаружили, что общие вершины вызывают эту проблему, вы можете протестировать этот код, если он вообще работает. Может когда-нибудь пригодится. Он направлен на назначение UV во время расчета сетки (специальные шейдеры больше не нужны), но требуется, чтобы смежные треугольники с углом между их независимыми нормалями > PI/4 нигде не имели общих вершин (другими словами: не было общих вершин между разными сторонами куба)

using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
    [SerializeField] MeshFilter meshFilter = null;
    Vector3[] vertices = { vertices goes here };
    int[] triangles = { indices goes here };
    void Start ()
    {
        Mesh mesh = new Mesh();
        meshFilter.mesh = mesh;

        Vector2[] uvs = new Vector2[ vertices.Length ];
        int numTriangles = triangles.Length / 3;
        for( int t=0 ; t<numTriangles ; t++ )
        {
            int ia = triangles[ t*3 ];
            int ib = triangles[ t*3+1 ];
            int ic = triangles[ t*3+2 ];

            Vector3 va = vertices[ ia ];
            Vector3 vb = vertices[ ib ];
            Vector3 vc = vertices[ ic ];

            Vector3 normal = Vector3.Cross( vb-va , vc-va ).normalized;
            float dotForward = Vector3.Dot( normal , Vector3.forward );
            float dotRight = Vector3.Dot( normal , Vector3.right );
            float dotUp = Vector3.Dot( normal , Vector3.up );

            if( dotForward>0.7071f )
            {
                // front projection
                uvs[ ia ] = new Vector2{ x=-va.x , y=va.y };
                uvs[ ib ] = new Vector2{ x=-vb.x , y=vb.y };
                uvs[ ic ] = new Vector2{ x=-vc.x , y=vc.y };
            }
            else if( dotForward<-0.7071f  )
            {
                // back projection
                uvs[ ia ] = new Vector2{ x=va.x , y=va.y };
                uvs[ ib ] = new Vector2{ x=vb.x , y=vb.y };
                uvs[ ic ] = new Vector2{ x=vc.x , y=vc.y };
            }
            else if( dotRight>0.7071f )
            {
                // right projection
                uvs[ ia ] = new Vector2{ x=-va.z , y=va.y };
                uvs[ ib ] = new Vector2{ x=-vb.z , y=vb.y };
                uvs[ ic ] = new Vector2{ x=-vc.z , y=vc.y };
            }
            else if( dotRight<-0.7071f )
            {
                // left projection
                uvs[ ia ] = new Vector2{ x=va.z , y=va.y };
                uvs[ ib ] = new Vector2{ x=vb.z , y=vb.y };
                uvs[ ic ] = new Vector2{ x=vc.z , y=vc.y };
            }
            else if( dotUp>0.7071f )
            {
                // top projection
                uvs[ ia ] = new Vector2{ x=-va.x , y=va.z };
                uvs[ ib ] = new Vector2{ x=-vb.x , y=vb.z };
                uvs[ ic ] = new Vector2{ x=-vc.x , y=vc.z };
            }
            else
            {
                // bottom projection
                uvs[ ia ] = new Vector2{ x=va.x , y=va.z };
                uvs[ ib ] = new Vector2{ x=vb.x , y=vb.z };
                uvs[ ic ] = new Vector2{ x=vc.x , y=vc.z };
            }
        }

        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.uv = uvs;

        mesh.RecalculateNormals();
    }
}
person Andrew Łukasik    schedule 22.12.2019

Я подозреваю, что коррекция текстуры перспективы в вашем случае отключена, потому что

Unity 2019.3: ♫ все круто ♫

введите здесь описание изображения

person Andrew Łukasik    schedule 22.12.2019
comment
Я только что поменял шейдер и все заработало, но бока искажаются, как ты не исказил? imgur.com/JUTNbEd - person victor oliveira; 22.12.2019
comment
Я использовал шейдер, который использует глобальное положение для текстур, но он не работал с этим шейдером, можете ли вы помочь мне, почему? codeshare.io/G7jdkk - person victor oliveira; 22.12.2019
comment
Вероятно, тогда этот шейдер отключил что-то, связанное с коррекцией текстуры перспективы. Потому что на стандартных (встроенных) таких проблем нет - person Andrew Łukasik; 22.12.2019
comment
Боковые стороны в моем случае тоже искажены, просто не так видны из-за другой текстуры. Это потому, что вы имитировали фронтальную проекцию - person Andrew Łukasik; 22.12.2019
comment
Если вы новичок в шейдерах и работаете с Unity 2019.3, я предлагаю вам создать свой шейдер в График шейдеров - person Andrew Łukasik; 22.12.2019
comment
Я использую Unity 2018, но подумываю перейти на 2019, есть много новых вещей, которые привлекают мое внимание, я начну учиться использовать Shader Graph, спасибо за подсказку! ;) - person victor oliveira; 22.12.2019
comment
Найдите узел Triplanar в Shader Graph. Он сэмплирует текстуры именно так, как вам нужно. - person Andrew Łukasik; 22.12.2019
comment
Но лучшим/правильным решением, безусловно, будет корректировка uv во время расчета сетки. Вы можете сделать это, вычислив вектор нормали треугольника и назначив uv на его основе. - person Andrew Łukasik; 22.12.2019
comment
Я расстроен, я воссоздал сетку с нуля и обнаружил ошибку, я делил некоторые вершины, а некоторые нет, и, видимо, это не сработало, но я не знал, что я не мог этого сделать, я сейчас используя тот шейдер, который использует глобальную позицию для текстуры, и все работает отлично, uv правильный. Но большое спасибо за внимание, чувак, я обновлю свой Unity и буду следовать твоим рекомендациям ‹3 - person victor oliveira; 22.12.2019
comment
Вам не нужно обновлять Unity, это было просто предложение при упоминании узла проекции Triplanar из Shader Graph. И это не нужно, так как вы поняли это. - person Andrew Łukasik; 22.12.2019