【发布时间】:2017-06-25 19:18:08
【问题描述】:
我在添加我自己的几何属性时遇到了这个错误。 我已经读过这个 WebGL GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1 ,我明白问题出在哪里,但我不知道为什么。
我正在构建一个 BufferGeometry,一棵树,从 1000 个对象开始。 300 个对象使用 LeafGeometry,700 个对象使用 BoxGeometry。
我想完成一个缓冲区,其中包含一个值,该值告诉一个顶点是属于树干还是属于树叶。我正在做的事情如下:
1) 首先我计算缓冲区的尺寸(这里我认为我做错了)调用:getTotNumVertices(LeafGeometry.new(options), BoxGeometry.new(options), 1000, 3000)
function getTotNumVertices(foliage_geometry, trunk_geometry, tot_objects, foliage_start_at){
let n_vertices_in_leaf = foliage_geometry.vertices.length * 3;
let n_vertices_in_trunk = trunk_geometry.vertices.length * 3;
let n_vertices_in_leafs = foliage_start_at * n_vertices_in_leaf;
let n_vertices_in_stam = (tot_objects - foliage_start_at) * n_vertices_in_trunk;
return{
tot_vertices: (n_vertices_in_stam + n_vertices_in_leafs),
n_vertices_leaf: n_vertices_in_leaf,
n_vertices_trunk: n_vertices_in_trunk
};
}
2)一旦我得到了顶点的总数,我就创建了缓冲区
function createBuffers(n_vert){
// I'm returnin an array becuase in my real code I'm returning
// more than one buffer
return {
isLeafBuffer: new Float32Array(n_vert)
};
}
3) 然后我构建我的 BufferGeometry,将 1000 个对象合并在一起:
let hash_vertex_info = getTotNumVertices(leafGeom, geometries["box"], 1000, 300);
let buffers = createBuffers(hash_vertex_info.tot_vertices);
let geometry = new THREE.Geometry();
let objs = buildTheTree(1000, 300);
for (let i = 0; i < objs.length; i++){
// here code that fullfills the buffers
let mesh = objs[i];
mesh.updateMatrix();
geometry.merge(mesh.geometry, mesh.matrix);
}
let bufGeometry = new THREE.BufferGeometry().fromGeometry(geometry);
console.log(bufGeometry.attributes.position.count);
console.log(hash_vertex_info.tot_vertices);
问题来了,bufGeometry.attributes.position.count 的值为 623616,hash_vertex_info.tot_vertices 的值为 308940。
绘制时,WebGL 尝试访问大于 308940 的值,然后出现错误。 我做错了什么?
//////////稍后编辑
基本上,我遇到了这个问题中解释的相同问题 Does converting a Geometry to a BufferGeometry in Three.js increase the number of vertices?
我需要计算顶点总数,以便创建一个包含着色器值的缓冲区。这是我的代码,合并后的几何体和从中获得的缓冲区几何体的顶点数仍然不同。
let tot_objects = 100;
let material = new THREE.MeshStandardMaterial( {color: 0x00ff00} );
let geometry = new THREE.BoxGeometry(5, 5, 5, 4, 4, 4);
let objs = populateGroup(geometry, material, tot_objects);
//let's merge all the objects in one geometry
let mergedGeometry = new THREE.Geometry();
for (let i = 0; i < objs.length; i++){
let mesh = objs[i];
mesh.updateMatrix();
mergedGeometry.merge(mesh.geometry, mesh.matrix);
}
let bufGeometry = new THREE.BufferGeometry().fromGeometry(mergedGeometry);
let totVerticesMergedGeometry = (mergedGeometry.vertices.length ) + (mergedGeometry.faces.length * 3);
console.log(bufGeometry.attributes.position.count); // 57600
console.log(totVerticesMergedGeometry); // 67400 !!!
scene.add(new THREE.Mesh(bufGeometry, material));
function populateGroup(selected_geometry, selected_material, tot_objects) {
let objects = [];
for (var i = 0; i< tot_objects; i++) {
let coord = {x:i, y:i, z:i};
let object = new THREE.Mesh(selected_geometry, selected_material);
object.position.set(coord.x, coord.y, coord.z);
object.rotateY( (90 + 40 + i * 100/tot_objects) * -Math.PI/180.0 );
objects.push(object);
}
return objects;
}
totVerticesMergedGeometry 和 bufGeometry.attributes.position.count 的个数应该一样,但还是不一样。
我计算顶点的方法错了吗?实际上这里使用的https://github.com/mrdoob/three.js/blob/master/src/core/DirectGeometry.js#L166是一样的,意思是(geometry.vertices.length) + (geometry.faces.length * 3)。
【问题讨论】:
-
我也有同样的想法。我已将对象的数量从 1000 减少到 100,但问题仍然存在。现在 bufGeometry.attributes.position.count 返回 105216,但我创建的缓冲区大小为 44340。这就是为什么我认为问题在于我计算几何中的顶点的方式。但我认为 geometry.vertices.length * 3 是正确的方法
-
我想我找到了正确的方向,stackoverflow.com/questions/33290544/… 我稍后会发布更新。我以错误的方式计算缓冲区的大小。 @gaitat,链接的答案来自你;)让我们看看它是否解决了我的问题
-
@gaitat 不,问题仍然存在。我在这个问题stackoverflow.com/questions/42130753/… 中更具体地确定了一个问题