THREE.JS glDrawElements:尝试访问属性 1 中超出范围的顶点

THREE.JS glDrawElements: attempt to access out of range vertices in attribute 1

我在添加自己的几何图形属性时遇到此错误。 我已经读过这个 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 的值,然后出现错误。 我做错了什么?

///////////稍后编辑

基本上,我遇到了这个问题中解释的相同问题

我需要计算顶点的总数,以便创建一个包含我的着色器值的缓冲区。这是我的代码,合并的几何图形和从中获得的缓冲区几何图形之间的顶点数仍然不同。

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).

我做错的是计算顶点数的方法。 用于缓冲区的顶点数用 MyObjectGeometry.faces.lenght * 3 * NumberOfObjectThatWillBeMerged 计算 更详细的答案在这里

我有这个错误,因为我用值而不是值数组调用构造函数:

-    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,
-    );
+    ] );