Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Unity has a Clockwise winding order?

Discussion in 'Scripting' started by yuzu_drink, Mar 29, 2012.

  1. yuzu_drink

    yuzu_drink

    Joined:
    Jan 15, 2012
    Posts:
    14
    I've been beating my head over this, and I can't find it anywhere in the documentation or forums. :(

    Can someone please confirm for me that Unity uses a CLOCKWISE winding order for determining front-facing polygons? I've been trying to figure it all out, and the only thing that's working to see my mesh is to use a clockwise winding order.

    Or amy I just doing it WAY wrong?

    Code (csharp):
    1. vertices[0] = new Vector3 (left, bottom, depth);
    2. vertices[1] = new Vector3 (right, bottom, depth);
    3. vertices[2] = new Vector3 (right, top, depth);
    4. vertices[3] = new Vector3 (left, top, depth);
    5.  
    6. uvs = new Vector2[4];
    7. uvs[0] = new Vector2 (0, 0);
    8. uvs[1] = new Vector2 (1, 0);
    9. uvs[2] = new Vector2 (1, 1);
    10. uvs[3] = new Vector2 (0, 1);
    11.  
    12. triangles = new int[6];
    13. triangles[0] = 0;
    14. triangles[1] = 2;
    15. triangles[2] = 1;
    16. triangles[3] = 2;
    17. triangles[4] = 0;
    18. triangles[5] = 3;
    Right?

    And doesn't most everyone else use a CCW winding order, or is that just OpenGL (by default)?
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Unity uses a clockwise winding order for determining front-facing polygons.

    No.

    --Eric
     
    somesome2314 and mgstraze like this.
  3. RakNet

    RakNet

    Joined:
    Oct 9, 2013
    Posts:
    315
    Unity uses a counter-clockwise winding order. See this code where I set the indices counter-clockwise. I originally set it clockwise based on what Eric5h5 claimed, and the mesh was upside down.

    Code (CSharp):
    1.  
    2. static public Mesh CreateTesselatedPlane(float width, float height, int segmentsWide, int segmentsHeight, Color defaultVertexColor)
    3.     {
    4.         Mesh mesh = new Mesh();
    5.         int numVerticesWide = segmentsWide + 1;
    6.         int numVerticesHeight = segmentsHeight + 1;
    7.         Color[] colors = new Color[numVerticesWide * numVerticesHeight];
    8.         Vector3[] normals = new Vector3[numVerticesWide * numVerticesHeight];
    9.         Vector3[] vertices = new Vector3[numVerticesWide * numVerticesHeight];
    10.         Vector2[] uvs = new Vector2[numVerticesWide * numVerticesHeight];
    11.         for (int h = 0; h < numVerticesHeight; h++)
    12.         {
    13.             for (int w = 0; w < numVerticesWide; w++)
    14.             {
    15.                 vertices[numVerticesWide * h + w] = new Vector3(
    16.                     -width / 2.0f + width * (float) w / (float) segmentsWide,
    17.                     0.0f,
    18.                     -height / 2.0f + height * (float) h / (float) segmentsHeight);
    19.  
    20.                 normals[numVerticesWide * h + w] = Vector3.up;
    21.                 colors[numVerticesWide * h + w] = defaultVertexColor;
    22.                 uvs[numVerticesWide * h + w] = new Vector2(Mathf.Min(1.0f, (float) w / (float) segmentsWide), Mathf.Min(1.0f, (float) h / (float) segmentsHeight));
    23.             }
    24.         }
    25.  
    26.         int[] indices = new int[6 * segmentsHeight * segmentsWide];
    27.         for (int h = 0; h < segmentsHeight; h++)
    28.         {
    29.             for (int w = 0; w < segmentsWide; w++)
    30.             {
    31.                 int upperLeftVertex = w + h * numVerticesWide;
    32.                 int upperRightVertex = w + h * numVerticesWide + 1;
    33.                 int lowerLeftVertex = w + (h+1) * numVerticesWide;
    34.                 int lowerRightVertex = w + (h+1) * numVerticesWide + 1;
    35.  
    36.                 indices[6 * (segmentsWide * h + w) + 0] = upperRightVertex;
    37.                 indices[6 * (segmentsWide * h + w) + 1] = upperLeftVertex;
    38.                 indices[6 * (segmentsWide * h + w) + 2] = lowerLeftVertex;
    39.                 indices[6 * (segmentsWide * h + w) + 3] = lowerLeftVertex;
    40.                 indices[6 * (segmentsWide * h + w) + 4] = lowerRightVertex;
    41.                 indices[6 * (segmentsWide * h + w) + 5] = upperRightVertex;
    42.             }
    43.         }
    44.  
    45.         mesh.vertices = vertices;
    46.         mesh.normals = normals;
    47.         mesh.colors = colors;
    48.         mesh.uv = uvs;
    49.         mesh.SetIndices(indices, MeshTopology.Triangles, 0);
    50.  
    51.         return mesh;
    52.     }
    53.  
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Nope.

    Code (csharp):
    1. var m = new Mesh();
    2. GetComponent<MeshFilter>().mesh = m;
    3. var verts = new Vector3[] {new Vector3(5, 5, 0), new Vector3(5, 0, 0), Vector3.zero};
    4. var tris = new int[] {0, 1, 2};
    5. m.vertices = verts;
    6. m.triangles = tris;
    Results in:

    mesh1.png

    Note the clockwise winding order. Reversing the triangle order to 2, 1, 0 results in:

    mesh2.png

    Counter-clockwise is invisible from this side (rotate the view to the other side and it's visible).

    --Eric
     
  5. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    2,000
    The code on top turns a quad into two tris. But if you're using SetIndices (instead of the older triangles=indices; method) you may as well use MeshTopology.Quads.

    As far as winding order, I'd guess upperRightVertex is in fact not really the upper right (or something similar.)
     
  6. JodyMagnopus

    JodyMagnopus

    Joined:
    Sep 17, 2016
    Posts:
    13
    The ordering is counter-clockwise if you are making triangles. I just did some procedural mesh generation and the faces were backwards unless I did them in counter-clockwise order.
     
  7. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    2,000
    It might be easier to think of it as the left-hand rule (similar to Unity's left-handed rule for axises). Wrap your left-hand fingers around the verts in order, and your thumb points out the front face.
     
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It is not. It's clockwise. Look at the post I made above a couple of years ago; there's pictures, code, and everything. Should not be hard to understand.

    --Eric
     
    Fingerbob likes this.
  9. Rickmc3280

    Rickmc3280

    Joined:
    Jun 28, 2014
    Posts:
    192
    Ran into issues where Raknets assumptions seem somewhat valid... found that it is best to start at the highest Y vector in the triangle (in unity) and work clockwise. If you start at the lowest and work clockwise it gives you issues on occasion. Also consider if you cant get the highest to work clockwise, get the furthest to the right and work clockwise.

    The best thing to do is just get the triangle, visualize the vectors inside of a clock and if its not possible to work from top -> right -> down -> left... (priority) well... maybe try lines xD. Works well with Clockwise in mind. (also if you want to flip a triangle replace triangle item 1 with item 3 and vice versa).

    ex (to flip)
    Original Triangle = 3 4 5
    New Triangle Flipped is 5 4 3 (where 3rd item is moved into first position, and 1st item is moved into the third position). Easy to just flip it if you are making procedural stuff or want to design your code to be able to flip the triangles.
     
    Last edited: Jun 3, 2021
  10. bixarrio

    bixarrio

    Joined:
    Dec 29, 2017
    Posts:
    18
    It's clockwise.
    Link from Unity Manual
    Quote:
    The ordering is important because you must order the corners clockwise