如何使用 Three.js 创建网格
How to create mesh with Three.js
我有一个 .obj 文件
v 1 2 3
v 4 5 6
v 7 8 9
vt 0 1
vt 1 0
vn 0 0 1
vn 0 1 0
vn 0 0 1
f 1/1/1 2/2/2 3/3/3
f 1/1/2 2/2/3 1/2/3
我需要创建 THREE.Mesh。我做
var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3));
geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
var mesh = new THREE.Mesh(geometry, material);
我想我需要在数组中包含以下数据:
var vertices = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var normals = [0, 0, 1, 0, 1, 0, 0, 0, 1];
var uvs = [0, 1, 1, 0]
var indices = // ... ?
我不明白我需要在索引数组中存储什么?
对于这个特定的例子:
var indices = [1, 2, 3, 1, 2, 1];
这将创建一个退化三角形,因为索引 1 对于同一个(即第二个)三角形出现两次。
有几种方法可以定义 .obj 格式的面元素:
f v1 v2 v3 .... // vertex indices
f v1/vt1 v2/vt2 v3/vt3 ... // adding texture indices
f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ... // adding normal indices
f v1//vn1 v2//vn2 v3//vn3 ... // eliminating texture indices
由于缓冲区使用顶点索引作为其属性,您将从三元组中选择第一个数字 (value1) value1/value2/value3 并形成 indices
数组。
这是我的示例,说明它应该是什么样子。面的定义表明,没有顶点具有相同的纹理和法线索引。因此,与正常 Geometry
中的其他情况一样,我们不能重用任何顶点,因为在 BufferGeometry
中,indices
数组中定义的索引适用于顶点、uvs 和法线数组。 (我认为,这就是@gaitat 试图解释的内容。)
v 1 2 3
v 4 5 6
v 7 8 9
vt 0 1
vt 0.5 0.5
vt 1 0
vn 0 0 1
vn 0 1 0
vn 1 0 0
f 1/1/1 2/2/2 3/3/3
f 1/1/2 2/2/3 1/2/3
var vertices = [1,2,3, 4,5,6, 7,8,9, 1,2,3, 4,5,6, 1,2,1]; // itemSize: 3
var uvs = [0,1, 0.5,0.5, 1,0, 0,1, 0.5,0.5, 0.5,0.5]; // itemSize: 2
var normals = [0,0,1, 0,1,0, 1,0,0, 0,1,0, 1,0,0, 1,0,0]; // itemSize: 3
var indices = [0,1,2, 3,4,5]; // itemSize: 1
编辑: 在上面的示例中,第一个面 (2/2/2
) 的第二个顶点用 1
。因此,我们将从顶点、uvs 和法线数组中获取第二个项目集:4,5,6
0.5,0.5
0,1,0
。第二个面的第二个顶点 (2/2/3
) 索引为 4
。因此,我们将从每个数组中获得第 5 个项目集:4,5,6
0.5,0.5
1,0,0
。两者的顶点位置和uv相同,但法线不同,所以不能重复使用。因为索引数组只为所有顶点存储一个索引,而不是为每个顶点位置、uv 和法线存储三个索引。
f 1/1/1 2/2/2 3/3/3
f 1/1/2 2/2/2 1/2/3
var vertices = [1,2,3, 4,5,6, 7,8,9, 1,2,3, 1,2,1]; // itemSize: 3
var uvs = [0,1, 0.5,0.5, 1,0, 0,1, 0.5,0.5]; // itemSize: 2
var normals = [0,0,1, 0,1,0, 1,0,0, 0,1,0, 1,0,0]; // itemSize: 3
var indices = [0,1,2, 3,1,5]; // itemSize: 1
在此示例中,两个面的第二个顶点相同 (2/2/2
)。在这种情况下,可以重复使用这些值。数组更短,第二个面中的顶点索引也是 1
。
我有一个 .obj 文件
v 1 2 3
v 4 5 6
v 7 8 9
vt 0 1
vt 1 0
vn 0 0 1
vn 0 1 0
vn 0 0 1
f 1/1/1 2/2/2 3/3/3
f 1/1/2 2/2/3 1/2/3
我需要创建 THREE.Mesh。我做
var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3));
geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
var mesh = new THREE.Mesh(geometry, material);
我想我需要在数组中包含以下数据:
var vertices = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var normals = [0, 0, 1, 0, 1, 0, 0, 0, 1];
var uvs = [0, 1, 1, 0]
var indices = // ... ?
我不明白我需要在索引数组中存储什么?
对于这个特定的例子:
var indices = [1, 2, 3, 1, 2, 1];
这将创建一个退化三角形,因为索引 1 对于同一个(即第二个)三角形出现两次。
有几种方法可以定义 .obj 格式的面元素:
f v1 v2 v3 .... // vertex indices
f v1/vt1 v2/vt2 v3/vt3 ... // adding texture indices
f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ... // adding normal indices
f v1//vn1 v2//vn2 v3//vn3 ... // eliminating texture indices
由于缓冲区使用顶点索引作为其属性,您将从三元组中选择第一个数字 (value1) value1/value2/value3 并形成 indices
数组。
这是我的示例,说明它应该是什么样子。面的定义表明,没有顶点具有相同的纹理和法线索引。因此,与正常 Geometry
中的其他情况一样,我们不能重用任何顶点,因为在 BufferGeometry
中,indices
数组中定义的索引适用于顶点、uvs 和法线数组。 (我认为,这就是@gaitat 试图解释的内容。)
v 1 2 3
v 4 5 6
v 7 8 9
vt 0 1
vt 0.5 0.5
vt 1 0
vn 0 0 1
vn 0 1 0
vn 1 0 0
f 1/1/1 2/2/2 3/3/3
f 1/1/2 2/2/3 1/2/3
var vertices = [1,2,3, 4,5,6, 7,8,9, 1,2,3, 4,5,6, 1,2,1]; // itemSize: 3
var uvs = [0,1, 0.5,0.5, 1,0, 0,1, 0.5,0.5, 0.5,0.5]; // itemSize: 2
var normals = [0,0,1, 0,1,0, 1,0,0, 0,1,0, 1,0,0, 1,0,0]; // itemSize: 3
var indices = [0,1,2, 3,4,5]; // itemSize: 1
编辑: 在上面的示例中,第一个面 (2/2/2
) 的第二个顶点用 1
。因此,我们将从顶点、uvs 和法线数组中获取第二个项目集:4,5,6
0.5,0.5
0,1,0
。第二个面的第二个顶点 (2/2/3
) 索引为 4
。因此,我们将从每个数组中获得第 5 个项目集:4,5,6
0.5,0.5
1,0,0
。两者的顶点位置和uv相同,但法线不同,所以不能重复使用。因为索引数组只为所有顶点存储一个索引,而不是为每个顶点位置、uv 和法线存储三个索引。
f 1/1/1 2/2/2 3/3/3
f 1/1/2 2/2/2 1/2/3
var vertices = [1,2,3, 4,5,6, 7,8,9, 1,2,3, 1,2,1]; // itemSize: 3
var uvs = [0,1, 0.5,0.5, 1,0, 0,1, 0.5,0.5]; // itemSize: 2
var normals = [0,0,1, 0,1,0, 1,0,0, 0,1,0, 1,0,0]; // itemSize: 3
var indices = [0,1,2, 3,1,5]; // itemSize: 1
在此示例中,两个面的第二个顶点相同 (2/2/2
)。在这种情况下,可以重复使用这些值。数组更短,第二个面中的顶点索引也是 1
。