1
$\begingroup$

When exporting a smooth-shaded default cube as .GLTF, Blender adds duplicate vertices. The GLTF file has 14 vertices, when there should be only 8 (smooth-shaded, so shared normals).

When I export to .OBJ or .DAE, no duplicate vertices are added. They both correctly hold only 8 vertices.

On further investigation, GLTF does this for every smooth-shaded model. It adds extra vertices where other formats don't. But this is wrong, as OpenGL does not need this extra data to render a smooth shaded cube. Duplicate verts are only required for flat-shaded meshes. In the case of a flat-shaded cube, Blender correctly exports to GLTF with 24 vertices.


To recreate: set default cube to shade smooth, and export. That's it.


EDIT: You've closed a question because you don't understand it. The "duplicate" question is answered on the basis of "Your model uses flat shading and you can see each vertex has multiple normals."

Whereas I am specifically referring to a smooth-shaded mesh (which means normals are shared, so no duplicates, no need for GLTF to repeat vertices beyond the 8 that make up a cube).

TLDR: FLAT SHADING VS SMOOTH SHADING is why they're different. Please reopen the question.

$\endgroup$
12
  • $\begingroup$ This is a duplicate question. See: blender.stackexchange.com/a/204766/18161 $\endgroup$
    – emackey
    Commented Aug 31, 2023 at 15:04
  • $\begingroup$ I focused my answer on your To recreate: setup but @emackey is right, its a duplicate. $\endgroup$
    – taiyo
    Commented Aug 31, 2023 at 15:56
  • $\begingroup$ Hello, KobeSystem.. it does look as though this is a duplicate, and fair to close. If for any reason the other answer isn't working for you, edit to point out the difference, and we can reopen for you. $\endgroup$
    – Robin Betts
    Commented Aug 31, 2023 at 17:49
  • $\begingroup$ This is not a duplicate. I've read that "duplicate" question, and I specifically addressed that answer in my question, when I specify smooth shading vs flat? $\endgroup$
    – KobeSystem
    Commented Sep 1, 2023 at 1:39
  • $\begingroup$ The issue happens with the default cube, but not with one created manually from extruding a plane. Maybe a bug, might be worth to use the menu Help > Report A Bug to be sure. $\endgroup$
    – Lauloque
    Commented Sep 1, 2023 at 2:53

1 Answer 1

2
$\begingroup$

In the glTF export dialog, untick Data > Mesh > UVs and you get your 8 vertices and normals. The other option is to remove the automatically created UVMap under the object's Data > UV Maps panel (then Data > Mesh > UVs can stay ticked).

Edit: Why does the glTF file for the default cube has 14 vertices?

Open Blender, set the shading of the default cube to Shade Smooth and run this script:

import bpy

obj = bpy.data.objects["Cube"]

# print all vertices with their uvs defining the cube
pairs = []
for face in obj.data.polygons:
    for vert_index, loop_index in zip(face.vertices, face.loop_indices):
        uv_coords = obj.data.uv_layers.active.data[loop_index].uv
        pairs.append((face.index, vert_index, uv_coords.x, uv_coords.y))
        print("face: %i, vertex: %i, uvs: %f, %f" % pairs[-1])

# print all vertices with their uvs which are unique
# and therefore must be stored
uniques = []
for pair in pairs:
    found = False
    for other in uniques:
        if pair[1] == other[1] and pair[2] == other[2] and pair[3] == other[3]:
            found = True
            break
    if not found:
        uniques.append(pair)
        
print(len(uniques), uniques)

This gives (Window > Toggle System Console):

face: 0, vertex: 0, uvs: 0.625000, 0.500000
face: 0, vertex: 4, uvs: 0.875000, 0.500000
face: 0, vertex: 6, uvs: 0.875000, 0.750000
face: 0, vertex: 2, uvs: 0.625000, 0.750000
face: 1, vertex: 3, uvs: 0.375000, 0.750000
face: 1, vertex: 2, uvs: 0.625000, 0.750000
face: 1, vertex: 6, uvs: 0.625000, 1.000000
face: 1, vertex: 7, uvs: 0.375000, 1.000000
face: 2, vertex: 7, uvs: 0.375000, 0.000000
face: 2, vertex: 6, uvs: 0.625000, 0.000000
face: 2, vertex: 4, uvs: 0.625000, 0.250000
face: 2, vertex: 5, uvs: 0.375000, 0.250000
face: 3, vertex: 5, uvs: 0.125000, 0.500000
face: 3, vertex: 1, uvs: 0.375000, 0.500000
face: 3, vertex: 3, uvs: 0.375000, 0.750000
face: 3, vertex: 7, uvs: 0.125000, 0.750000
face: 4, vertex: 1, uvs: 0.375000, 0.500000
face: 4, vertex: 0, uvs: 0.625000, 0.500000
face: 4, vertex: 2, uvs: 0.625000, 0.750000
face: 4, vertex: 3, uvs: 0.375000, 0.750000
face: 5, vertex: 5, uvs: 0.375000, 0.250000
face: 5, vertex: 4, uvs: 0.625000, 0.250000
face: 5, vertex: 0, uvs: 0.625000, 0.500000
face: 5, vertex: 1, uvs: 0.375000, 0.500000
14 [(0, 0, 0.625, 0.5), (0, 4, 0.875, 0.5), (0, 6, 0.875, 0.75), (0, 2, 0.625, 0.75), (1, 3, 0.375, 0.75), (1, 6, 0.625, 1.0), (1, 7, 0.375, 1.0), (2, 7, 0.375, 0.0), (2, 6, 0.625, 0.0), (2, 4, 0.625, 0.25), (2, 5, 0.375, 0.25), (3, 5, 0.125, 0.5), (3, 1, 0.375, 0.5), (3, 7, 0.125, 0.75)]

As one can see, there are 14 unique uv'ed vertices to keep track of.

Edit2: note that there are only 8 vertices as it should be. A vertex (representing only a position) is not the same as an uv'ed vertex (representing a position and an uv attribute).

Do the same with an extruded plane, this will give this output:

face: 0, vertex: 0, uvs: 0.000000, 0.000000
face: 0, vertex: 2, uvs: 0.000000, 1.000000
face: 0, vertex: 3, uvs: 1.000000, 1.000000
face: 0, vertex: 1, uvs: 1.000000, 0.000000
face: 1, vertex: 5, uvs: 0.000000, 0.000000
face: 1, vertex: 6, uvs: 1.000000, 0.000000
face: 1, vertex: 7, uvs: 1.000000, 1.000000
face: 1, vertex: 4, uvs: 0.000000, 1.000000
face: 2, vertex: 3, uvs: 1.000000, 1.000000
face: 2, vertex: 2, uvs: 0.000000, 1.000000
face: 2, vertex: 4, uvs: 0.000000, 1.000000
face: 2, vertex: 7, uvs: 1.000000, 1.000000
face: 3, vertex: 0, uvs: 0.000000, 0.000000
face: 3, vertex: 1, uvs: 1.000000, 0.000000
face: 3, vertex: 6, uvs: 1.000000, 0.000000
face: 3, vertex: 5, uvs: 0.000000, 0.000000
face: 4, vertex: 1, uvs: 1.000000, 0.000000
face: 4, vertex: 3, uvs: 1.000000, 1.000000
face: 4, vertex: 7, uvs: 1.000000, 1.000000
face: 4, vertex: 6, uvs: 1.000000, 0.000000
face: 5, vertex: 2, uvs: 0.000000, 1.000000
face: 5, vertex: 0, uvs: 0.000000, 0.000000
face: 5, vertex: 5, uvs: 0.000000, 0.000000
face: 5, vertex: 4, uvs: 0.000000, 1.000000
8 [(0, 0, 0.0, 0.0), (0, 2, 0.0, 1.0), (0, 3, 1.0, 1.0), (0, 1, 1.0, 0.0), (1, 5, 0.0, 0.0), (1, 6, 1.0, 0.0), (1, 7, 1.0, 1.0), (1, 4, 0.0, 1.0)]

Now there are only 8 unique uv'ed vertices, because the created uv map is different. As image (for the default cube, Blender created a nice cube net, but for the extruded plane all sides have the same uv square):

enter image description here

Therefore, the following export glTF behaviour can be observed:

Shade Smooth                 | Default Cube | Extruded Plane
----------------------------------------------------------
Data > Mesh > UVs ticked     |    14        |      8
Data > Mesh > UVs unticked   |     8        |      8

In the glTF file the information can be found under:

{
    ...
    "accessors":[
        {
            "bufferView":0,
            ...
            "count":14,   <-- here
            ...
        },
        ...
} 

Note: the other answer states

To handle this there are "duplicate" glTF verts (that have the same position, but different normals). The same thing happens for all other "vertex per poly" data, like UVs. "Duplicate" verts are inserted only when necessary, so turn off export of anything you don't need—normals, tangents, UVs, vertex colors, materials—to get a smaller glTF vert count.

which is why this question is considered a duplicate.

$\endgroup$
3
  • $\begingroup$ I've done this and still the GLTF file has 14 vertices and 14 normals. Also I'm exporting to GLTF (not GLB). $\endgroup$
    – KobeSystem
    Commented Sep 1, 2023 at 1:46
  • $\begingroup$ @KobeSystem I've exported to glTF too. Which Blender version are you using? $\endgroup$
    – taiyo
    Commented Sep 1, 2023 at 6:31
  • $\begingroup$ Great, thanks. I see now. Your image of the two UV maps side by side cleared things up for me. The other question was focused on duplicates due to flat-shading/extra normals, but you're right the answer mentions that it affects all attributes. However your side by side UV maps helped me to properly think that through. $\endgroup$
    – KobeSystem
    Commented Sep 1, 2023 at 16:23

You must log in to answer this question.

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