我在添加自己的几何属性时遇到此错误。 我已经阅读了这个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)。
答案 0 :(得分:0)
我做错了是计算顶点数的方法。 使用MyObjectGeometry.faces.lenght计算用于缓冲区的顶点数* 3 * NumberOfObjectThatWillBeMerged 这里有一个更详细的答案Why the number of vertices in a merged Geometry differs from the number of vertices in the BufferedGeometry obtained from it?
答案 1 :(得分:0)
我遇到了这个错误,因为我使用值而不是值数组调用构造函数:
- var colors = new Float32Array(
+ var colors = new Float32Array( [
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 1.0,
0.0, 1.0, 1.0,
1.0, 1.0, 1.0,
- );
+ ] );