4
\$\begingroup\$

I want to understand logic behind drawing triangles of primitives in Unity. When we spawn simple cube, variable mesh.vertexCount gives us value 24. Also when we list all vertices positions (from mesh.vertices) and triangles numbers (from mesh.triangles), we get:

0. (1.0, -1.0, 1.0) 0
1. (-1.0, -1.0, 1.0) 2
2. (1.0, 1.0, 1.0) 3
3. (-1.0, 1.0, 1.0) 0
4. (1.0, 1.0, -1.0) 3
5. (-1.0, 1.0, -1.0) 1
6. (1.0, -1.0, -1.0) 8
7. (-1.0, -1.0, -1.0) 4
8. (1.0, 1.0, 1.0) 5
9. (-1.0, 1.0, 1.0) 8
10. (1.0, 1.0, -1.0) 5
11. (-1.0, 1.0, -1.0) 9
12. (1.0, -1.0, -1.0) 10
13. (1.0, -1.0, 1.0) 6
14. (-1.0, -1.0, 1.0) 7
15. (-1.0, -1.0, -1.0) 10
16. (-1.0, -1.0, 1.0) 7
17. (-1.0, 1.0, 1.0) 11
18. (-1.0, 1.0, -1.0) 12
19. (-1.0, -1.0, -1.0) 13
20. (1.0, -1.0, -1.0) 14
21. (1.0, 1.0, -1.0) 12
22. (1.0, 1.0, 1.0) 14
23. (1.0, -1.0, 1.0) 15

(i-th element, vector from mesh.vertices[i], number from mesh.triangles[i])

Obviously we need only 8 vertices to create cube, but we need 6*2=12 triangles, three vertices every - array of 36 vectors. So... what is the logic of Unity primitive?

\$\endgroup\$
1
  • \$\begingroup\$ Ok I discovered that mesh.triangles has length of 36 integers, so at least this one is logical. But why we have 24 vertices instead of 8? \$\endgroup\$ Jul 22, 2016 at 9:46

2 Answers 2

5
\$\begingroup\$

In computer graphics, a vertex is usually more than just a position: it also includes texture coordinates and normal (facing direction) information (among other situational data, like vertex colours, blend weights, tangent vectors, etc...)

The vertex processing part of the graphics pipeline doesn't index these sets of information independently — all the information needed to build the triangles is indexed with just one array of indices. (At least that's the standard way — there may be more exotic techniques)

So to represent the same point in space but with different texture coordinates and normals, we need to duplicate the whole vertex, resulting in copies of the same position in the vertex position array. If you look at the uv and nornal arrays though, you'll find the vertices in these duplicated slots differ in other ways.

Bringing this together: while a cube contains 8 unique corner positions, if we look closely at any one corner we find 3 faces meeting along sharp edges. That means 3 surface normals are needed to represent that corner vertex, one for each adjacent face.

8 corner positions × 3 faces per corner = 24

So that's where the 24 number comes from. Each of the 8 unique vertex positions needs to be repeated 3 times to describe the different surface facing directions meeting at that point.

If we had only 8 vertices, we couldn't give each face meeting at a corner its own unique normal, so the cube would get shaded like a rounded blob, without the sharp edges we expect to see.

You may find 3D modelling software gives a different count. For editing a model, they'll typically treat shared vertices as a single object so it's easier to move parts around without creating gaps. Even these programs still usually split shared vertices into copies for each unique combo of vertex attributes on export, or the game engine does this on import, to make something friendly for GPU consumption.

\$\endgroup\$
1
\$\begingroup\$

It doesn't count unique vertices (as defined by their positions), but vertices as they are used to generate triangles.

Look at your list, vertex #0 and #13 are the same vertex, but as DM Gregory's answer will detail, have other different attributes like surface normals, so even indexed, the positions aren't enough to index (although in theory you could index positions and normals separately, it doesn't perform well in practice). Now another side of this is that you could collapse similar vertices that have very similar (read: indistinguishable) positions, normals, and other attributes and you could eliminate duplicates and index those. For example: a mesh of more natural shapes might have many vertices that have identical face normals and should be one vertex that is indexed.

\$\endgroup\$
2
  • \$\begingroup\$ I think you may have misunderstood the question. Drawing a straight triangle list without separate triangle indices would give 36 vertices, not the 24 OP observes in their data. OP also mentions that the cube they're examining does use a separate list of indices (36 ints long), so they're wondering why the vertex array has 24 entries instead of just the 8 unique corner positions. \$\endgroup\$
    – DMGregory
    Jul 22, 2016 at 11:56
  • \$\begingroup\$ @DMGregory Yes, thank you for pointing that out, but my primary point still stands that "It doesn't count unique vertices (as defined by their positions), but vertices as they are used to generate triangles." I've extended my answer to highlight the fact that surface normals can be reduced and indexed, please let me know if you find my edits inaccurate or find other issue with them. \$\endgroup\$
    – user5665
    Jul 22, 2016 at 12:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .