这是一个正确的glTF文件吗?存在重复的顶点。

huangapple go评论76阅读模式
英文:

Is this a correct glTF file? There are duplicate vertices

问题

I am working with blender 3.6 and I have exported a simple cube under the glTF format:

我正在使用 Blender 3.6,并将一个简单的立方体导出为 glTF 格式:

{
"asset": {
"generator": "Khronos glTF Blender I/O v3.6.27",
"version": "2.0"
},
"scene": 0,
"scenes": [
{
"name": "Scene",
"nodes": [
0
]
}
],
"nodes": [
{
"mesh": 0,
"name": "Cube"
}
],
"materials": [
{
"doubleSided": true,
"name": "Material",
"pbrMetallicRoughness": {
"baseColorFactor": [
0.800000011920929,
0.800000011920929,
0.800000011920929,
1
],
"metallicFactor": 0,
"roughnessFactor": 0.5
}
}
],
"meshes": [
{
"name": "Cube",
"primitives": [
{
"attributes": {
"POSITION": 0,
"NORMAL": 1,
"TEXCOORD_0": 2
},
"indices": 3,
"material": 0
}
]
}
],
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 24,
"max": [
1,
1,
1
],
"min": [
-1,
-1,
-1
],
"type": "VEC3"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 24,
"type": "VEC3"
},
{
"bufferView": 2,
"componentType": 5126,
"count": 24,
"type": "VEC2"
},
{
"bufferView": 3,
"componentType": 5123,
"count": 36,
"type": "SCALAR"
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 288,
"byteOffset": 0,
"target": 34962
},
{
"buffer": 0,
"byteLength": 288,
"byteOffset": 288,
"target": 34962
},
{
"buffer": 0,
"byteLength": 192,
"byteOffset": 576,
"target": 34962
},
{
"buffer": 0,
"byteLength": 72,
"byteOffset": 768,
"target": 34963
}
],
"buffers": [
{
"byteLength": 840,
"uri": "data:application/octet-stream;base64,AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAvwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAQD8AACA/AABAPwAAYD8AAAA/AADAPgAAQD8AAAA+AAAAPwAAwD4AAEA/AAAgPwAAgD8AACA/AAAAAAAAYD8AAIA+AADAPgAAgD8AAAA+AACAPgAAwD4AAAAAAQAOABQAAQAUAAcACgAGABMACgATABcAFQASAAwAFQAMAA8AEAADAAkAEAAJABYABQACAAgABQAIAAsAEQANAAAAEQAAAAQA"
}
]
}

The mesh itself is a simple cube (the first object Blender gives you when you create a new project), which should have 8 vertices, one for each corner of the cube, right?

这个网格本身是一个简单的立方体(在创建新项目时Blender给出的第一个对象),应该有8个顶点,每个顶点对应立方体的一个角,对吗?

I would like to draw your attention to the first buffer view and the first accessor, they refer to the position values (the vertices). The accessor says there are 24 elements, the component type is 5126, which stands for float 32bit, i.e., 4 bytes. Given the data type is VEC3, there should be 12 bytes (3 * 4) per element right? This means that there should be 8 * 12 = 96 bytes in the buffer view. Then why does the buffer view have 288 = 3 * 96 bytes in it, and why, when I print the data in the buffer view, do I get triple the same output:

我想引起你的注意,第一个缓冲视图和第一个访问器引用了位置值

英文:

I am working with blender 3.6 and I have exported a simple cube under the glTF format:

{
	"asset":{
		"generator":"Khronos glTF Blender I/O v3.6.27",
		"version":"2.0"
	},
	"scene":0,
	"scenes":[
		{
			"name":"Scene",
			"nodes":[
				0
			]
		}
	],
	"nodes":[
		{
			"mesh":0,
			"name":"Cube"
		}
	],
	"materials":[
		{
			"doubleSided":true,
			"name":"Material",
			"pbrMetallicRoughness":{
				"baseColorFactor":[
					0.800000011920929,
					0.800000011920929,
					0.800000011920929,
					1
				],
				"metallicFactor":0,
				"roughnessFactor":0.5
			}
		}
	],
	"meshes":[
		{
			"name":"Cube",
			"primitives":[
				{
					"attributes":{
						"POSITION":0,
						"NORMAL":1,
						"TEXCOORD_0":2
					},
					"indices":3,
					"material":0
				}
			]
		}
	],
	"accessors":[
		{
			"bufferView":0,
			"componentType":5126,
			"count":24,
			"max":[
				1,
				1,
				1
			],
			"min":[
				-1,
				-1,
				-1
			],
			"type":"VEC3"
		},
		{
			"bufferView":1,
			"componentType":5126,
			"count":24,
			"type":"VEC3"
		},
		{
			"bufferView":2,
			"componentType":5126,
			"count":24,
			"type":"VEC2"
		},
		{
			"bufferView":3,
			"componentType":5123,
			"count":36,
			"type":"SCALAR"
		}
	],
	"bufferViews":[
		{
			"buffer":0,
			"byteLength":288,
			"byteOffset":0,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":288,
			"byteOffset":288,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":192,
			"byteOffset":576,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":72,
			"byteOffset":768,
			"target":34963
		}
	],
	"buffers":[
		{
			"byteLength":840,
			"uri":"data:application/octet-stream;base64,AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAvwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAQD8AACA/AABAPwAAYD8AAAA/AADAPgAAQD8AAAA+AAAAPwAAwD4AAEA/AAAgPwAAgD8AACA/AAAAAAAAYD8AAIA+AADAPgAAgD8AAAA+AACAPgAAwD4AAAAAAQAOABQAAQAUAAcACgAGABMACgATABcAFQASAAwAFQAMAA8AEAADAAkAEAAJABYABQACAAgABQAIAAsAEQANAAAAEQAAAAQA"
		}
	]
}

The mesh itself is a simple cube (the first object Blender gives you when you create a new project), which should have 8 vertices, one for each corner of the cube, right?

I would like to draw your attention to the first buffer view and the first accessor, they refer to the position values (the vertices). The accessor says there are 24 elements, the component type is 5126, which stands for float 32bit, i.e., 4 bytes. Given the the data type is VEC3, there should be 12 bytes (3 * 4) per element right? This means that there should be 8 * 12 = 96 bytes in the buffer view. Then why does the buffer view have 288 = 3 * 96 bytes in it, and why, when I print the data in the buffer view, do I get triple the same output:

1.000000, 1.000000, -1.000000

1.000000, 1.000000, -1.000000

1.000000, 1.000000, -1.000000

1.000000, -1.000000, -1.000000

1.000000, -1.000000, -1.000000

1.000000, -1.000000, -1.000000

1.000000, 1.000000, 1.000000

1.000000, 1.000000, 1.000000

1.000000, 1.000000, 1.000000

1.000000, -1.000000, 1.000000

1.000000, -1.000000, 1.000000

1.000000, -1.000000, 1.000000

-1.000000, 1.000000, -1.000000

-1.000000, 1.000000, -1.000000

-1.000000, 1.000000, -1.000000

-1.000000, -1.000000, -1.000000

-1.000000, -1.000000, -1.000000

-1.000000, -1.000000, -1.000000

-1.000000, 1.000000, 1.000000

-1.000000, 1.000000, 1.000000

-1.000000, 1.000000, 1.000000

-1.000000, -1.000000, 1.000000

-1.000000, -1.000000, 1.000000

-1.000000, -1.000000, 1.000000

Notice how there are always three vectors that are the same, and notice how there are indeed 24 vectors. The following is a .obj file which is exported from the exact same blender mesh (i.e., no operations were performed during both exports):

# Blender v3.6.0 OBJ File: ''
# www.blender.org
mtllib untitled.mtl
o Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vt 0.625000 0.500000
vt 0.875000 0.500000
vt 0.875000 0.750000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.125000 0.500000
vt 0.375000 0.500000
vt 0.125000 0.750000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
usemtl Material
s off
f 1/1/1 5/2/1 7/3/1 3/4/1
f 4/5/2 3/4/2 7/6/2 8/7/2
f 8/8/3 7/9/3 5/10/3 6/11/3
f 6/12/4 2/13/4 4/5/4 8/14/4
f 2/13/5 1/1/5 3/4/5 4/5/5
f 6/11/6 5/10/6 1/1/6 2/13/6

There should indeed be 8 vertices, which is always displayed inside blender with the statistics option enabled.

The code (C) used to print the vectors is the following:

vec3* positions = bin + position_view->byte_offset;

for (int i = 0; i < position_accessor->count; i++) {
    printf("%f, %f, %f\n", positions[i][0], positions[i][1], positions[i][2]);
    printf("\n");
}

where bin is a void* containing the entire contents of the buffer, vec3 is a cglm type, it is actually a float[3], position_view->byte_offset is 0 and position_accessor->count 24 as in the .gltf file above.

My intuition says that the "count":24 property in the first accessor should be 8, and that the buffer view should indeed have a length of 96, as such the other accessors and buffers are also wrong as they are the normals and texture coordinates (the indices seem to be correct).

What puzzles me the most is that if I upload the .gltf file an onliner gltf viewer, the mesh is in fact rendered correctly, for example on this website https://gltf-viewer.donmccurdy.com/
If the file is correct, then why is each vertex tripled? Maybe I am interpreting the positions array (vec3*, i.e., 'float[3]*') wrong?

Thanks.

答案1

得分: 1

一个具有硬边的立方体在GPU准备的顶点流中不能仅有8个顶点,这正是glTF格式提供的内容。每个顶点都存储一个法线向量,每个面都有不同的法线,因此您需要6 * 4 = 24个顶点。如果您在Blender的导出选项中禁用了顶点法线(也可能是UV),您可能会看到8个顶点,就像您所期望的那样。

这个来自Blender Stack Exchange的回答可能也会有所帮助 — https://blender.stackexchange.com/a/167383/43930

英文:

A cube with hard edges cannot have only 8 vertices in a GPU-ready vertex stream – which is what the glTF format provides. Each vertex stores a normal vector, each face has different normals, and so you need 6 * 4 = 24 vertices. If you disable vertex normals (and perhaps also UVs) in Blender's export options, you will likely see 8 vertices as you'd expect.

This response from the Blender Stack Exchange may also be helpful — https://blender.stackexchange.com/a/167383/43930.

huangapple
  • 本文由 发表于 2023年7月13日 21:25:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76679878.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定