2017-02-08 9 views
0

У меня возникает эта ошибка при добавлении атрибута моей геометрии. Я уже прочитал это WebGL GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1, и я понимаю, в чем проблема, но я не могу понять, почему.THREE.JS glDrawElements: попытка получить доступ к вершинам диапазона значений в атрибуте 1

Я строю BufferGeometry, дерево, начиная с 1000 объектов. 300 объектов используют LeafGeometry, 700 объектов используют BoxGeometry.

Я хочу выполнить буфер, содержащий значение, которое указывает, принадлежит ли вершина к стволу или к листву. Что я делаю, так это следующее:

1) Сначала я вычисляю размер буфера (и здесь я думаю, что я делаю это неправильно), вызывающий: getTotNumVertices (LeafGeometry.new (options), BoxGeometry.new (варианты), 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, а затем ошибка. Что я делаю неправильно?

/////////// EDIT через некоторое время

В принципе, у меня перед той же проблемой объяснил в этом вопросе 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

может быть, из-за http://stackoverflow.com/questions/4998278/is-there-a-limit-of-vertices-in-webgl, https://forums.khronos.org /showthread.php/6762-Maximum-size-for-index-buffer-and-how-to-go-around-it – gaitat

+0

Я тоже думал об этом. Я уменьшил количество объектов, от 1000 до 100, но проблема все еще сохраняется.Теперь bufGeometry.attributes.position.count возвращает 105216, но созданный мной буфер имеет размер 44340. Вот почему я думаю, что проблема в том, как я рассчитываю вершины в геометрии. Но я думаю, что geometry.vertices.length * 3 - правильный способ сделать это. – edap

+0

Я думаю, что нашел правильный трек, http://stackoverflow.com/questions/33290544/does-converting-a-geometry-to -a-buffergeometry-in-three-js-increase-the-number-o i позже опубликует обновления. Я неправильно вычисляю размер буфера. @gaitat, связанный ответ приходит от вас;) давайте посмотрим, исправляет ли моя проблема – edap

ответ

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?

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