I'm having a hard time undestanding how to read the vertex array properly when GLTF is exported with/without normals, uvs.

For the start, I've exported the basic Blender cube without any normals or uvs. As expected, the position vertex buffer consisted of 24 floats (96 bytes), representing 8 vertices, and the indices buffer consisted of 36 ushorts ranging from 0 to 7. By this far everything is very intuitive.

Once I've added UV's to the export, the position buffer became 168 bytes long, consisting of 14 vertices. As well, a TEXCOORD buffer was added, having 112 bytes. Indices buffer remained of same count (36), but now ranges from 0 to 13.

Once normals were added to the export, the position buffer count grew to be 24. I understand that it is now representing 3 vertices of same position with different normals to allow rendering sharp edges. As well, a new buffer was added to represent the normal vector of each position vertex. Now the indices have range of 0 to 23.

Now, if I remove UV's from the export, the position buffer remains with the same size including normals, having 24 vertices. The indices have the same range. The only thing that changes is that there is no longer a buffer of TEXCOORD present.

Except for the primitive case of position vertices only, I can't figure out how the indices map onto the position buffer. Why the position buffer for POS + UV + NORMAL == POS + NORMAL, but POS + UV != POS?

I've gone through the GLTF spec, but couldn't find any info on this regard. Also, I've tried to look at threejs sources (GLTFLoader, Mesh, BufferGeometry, etc.), but it gave me no clue either.

P.S. I'm new to 3D, have no prior knowledge of 3d data arrangement, mapping, etc. If there is too much to explain, please advise of a good resource/book to read.


1 Answer 1


I think what you're seeing here is that some vertices in Blender's default cube share UVs without sharing normals, so exporting with POS+UV requires at least 14 vertices. Normals have more variance than UVs, and require 24 unique vertices when normals are present.

The maximum number of vertices that could be required for a particular mesh is (triangleCount * 3), or 6 * 2 * 3 = 36 for a basic cube, if each triangle has unique data associated with its vertices.

Ultimately this question is linked to specific data in this specific cube. Modify the UVs and you'll get a different result. Or another exporter could choose a different vertex layout, e.g. with interleaved vertices, or duplicating vertices with shared normals out of simplicity. The glTF specification allows flexility to optimize the vertex stream, or to fully unpack it, at the exporter's discretion. Various tools can also post-process a glTF file to optimize the vertex stream after export, which would again change the structure.


You must log in to answer this question.

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