1

I'm learning how to mesh by code in Unity, but the texture is weird as in the image, does anyone know why this is? I created the UV Map as it is in the code, searched Google and Unity documentation a lot, and saw that I should use the array vertices to map the UV, but I think I did something wrong https://i.stack.imgur.com/F4uo8.png

My Code:

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;
Andrew Łukasik
  • 1,454
  • 12
  • 19
victor oliveira
  • 89
  • 1
  • 1
  • 6

2 Answers2

1

Since you already discovered that shared vertices were causing this issue you may want to test this code if it even works. May become useful at some point. It aims at assigning UVs at mesh computation time (special shaders no longer needed), but requires that adjacent triangles with angle between their independent normals > PI/4 share no vertices anywhere (in other words: no shared vertices between different sides of a cube)

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();
    }
}
Andrew Łukasik
  • 1,454
  • 12
  • 19
0

I suspect that perspective texture correction is disabled in your case because

Unity 2019.3: ♫ everything is awesome ♫

enter image description here

Andrew Łukasik
  • 1,454
  • 12
  • 19
  • I just changed shader and it worked, but the sides are distorted, how did you not to get distorted? https://imgur.com/JUTNbEd – victor oliveira Dec 22 '19 at 15:49
  • 1
    I was using a shader that uses global position for the textures, but it didn't work with this shader, can you help me why? https://codeshare.io/G7jdkk – victor oliveira Dec 22 '19 at 15:53
  • This shader probably disabled something related with "perspective texture correction" then. Because there is no such problems on standard (built-in) ones – Andrew Łukasik Dec 22 '19 at 15:55
  • The sides are distorted in my case too, just not as visible due to different texture. That's because you emulated kind of frontal projection – Andrew Łukasik Dec 22 '19 at 15:59
  • If you're new to shaders and working on Unity 2019.3 I suggest you make your shader in [Shader Graph](https://blogs.unity3d.com/2018/02/27/introduction-to-shader-graph-build-your-shaders-with-a-visual-editor/) – Andrew Łukasik Dec 22 '19 at 16:01
  • I'm using Unity 2018, but I'm thinking of moving to 2019, there's a lot of new things that are catching my attention, I'll start learning to use Shader Graph, thanks for the tip! ;) – victor oliveira Dec 22 '19 at 16:05
  • Look for "Triplanar" node in Shader Graph. It samples textures exactly the way you need here – Andrew Łukasik Dec 22 '19 at 16:27
  • But the best/correct solution will be definitely to correct uv at mesh computation time. You can do this by calculating triangle normal vector and assigning uv based on that. – Andrew Łukasik Dec 22 '19 at 16:38
  • I'm frustrated, I recreated the mesh from scratch and discovered the error, I was sharing some vertices and some not, and apparently it didn't work, but I didn't know I couldn't do that, I'm now using that shader that uses global position for texture and everything is working perfectly, the uv is correct. But thank you so much for your attention man, I will update my Unity and follow your recommendations <3 – victor oliveira Dec 22 '19 at 17:33
  • You don't need to update Unity, that was just a suggestion when mentioning Triplanar projection node from Shader Graph. And it's unnecessary since you figured it out. – Andrew Łukasik Dec 22 '19 at 18:21