How to UV map all 6 faces of a cube but draw it using Indices with only 8 Vertex data?

I’m drawing a cube with the following code but the problem is that I can not map all the UVs correctly. I know that the reason is that I only define 8 vertex positions and then I use 36 indices to draw all the 6 faces of the cube and this leads to the problem that I can’t write down all the Uv’s because each vertex (8 in total in this case) can only have 8 Uvs as well.

I don’t want to use 36 Vertex data to map all the Uvs for each vertex. There must be a way to do this else Index drawing would be meaningless…

using UnityEngine;

public class Vortex : MonoBehaviour
{

    [SerializeField] private MeshFilter   m_MeshFilter;
    [SerializeField] private MeshRenderer m_MeshRenderer;




    // Start is called before the first frame update
    void Start()
    {

        //Create a new mesh objet.
        Mesh mesh = new Mesh();

        //Create the vertex data.
        mesh.vertices = new Vector3[]
        {
            new Vector3(0.0f, 0.0f, 0.0f), //Front-Left Bottom   (0)
            new Vector3(0.0f, 1.0f, 0.0f), //Front-Left Top      (1)
            new Vector3(1.0f, 1.0f, 0.0f), //Front-Right Top     (2)
            new Vector3(1.0f, 0.0f, 0.0f), //Front-Right Bottom  (3)

            new Vector3(0.0f, 0.0f, 1.0f), //Back-Left Bottom    (4)
            new Vector3(0.0f, 1.0f, 1.0f), //Back-Left Top       (5)
            new Vector3(1.0f, 1.0f, 1.0f), //Back-Right Top      (6)
            new Vector3(1.0f, 0.0f, 1.0f)  //Back-Right Bottom   (7)
        };


        //Create the Indices.
        mesh.triangles = new int[]
        {
            0, 1, 2, 3, 0, 2, //Front Face.
            1, 5, 6, 2, 1, 6, //Top Face.
            4, 5, 1, 0, 4, 1, //Left Face.
            3, 2, 6, 7, 3, 6, //Right Face.
            6, 5, 4, 6, 4, 7, //Back Face.
            4, 0, 3, 7, 4, 3, //Bottom Face.
        };



        //Texture Coordinates.
        mesh.uv = new Vector2[]
        {
            new Vector2(0.0f, 0.0f),
            new Vector2(0.0f, 1.0f),
            new Vector2(1.0f, 1.0f),
            new Vector2(1.0f, 0.0f),

            new Vector2(1.0f, 0.0f),
            new Vector2(1.0f, 1.0f),
            new Vector2(0.0f, 1.0f),
            new Vector2(0.0f, 0.0f),
        };


        //Recalculate Normals.
        mesh.RecalculateNormals();


        //Set the mesh to the mesh filter.
        m_MeshFilter.mesh = mesh;
    }
}

If the question is “how do assign UVs for this mesh that will work for any generic shader and doesn’t have weird stretching”, the answer is you can’t. You must add additional unique vertices to your mesh. You need a minimum of 14 vertices to get something at least similar to how Unity’s default Cube mesh is UV mapped.

If the question is “how can I UV map a mesh with no seams with a custom shader”, then the answer is lots of ways! You could use some form of triplanar mapping, or a cube map, or use the math used by cube maps to get per face UVs from a 3D vector. And then the mesh generation problem changes trying to figure out how to map a 2D projection onto a 3D object to just needing to use the object space vertex positions in the shader, or store a Vector3 “UVW” instead of a Vector2 UV. Which option is “best” depends on what you’re ultimately looking to do.

1 Like