2013-07-01 11 views
5

Sto usando un BufferGeometry per disegnare migliaia di cubi che costituiscono il terreno, ma ho difficoltà a trovare come aggiornare la geometria se ho bisogno di cambiare la posizione di uno dei cubi. Per esempio, io ho questo codice per inizializzare la mia geometria: (Sto facendo del mio test su una versione aggiornata di this example)Come aggiornare rapidamente un grande BufferGeometry?

// 12 triangles per cube (6 quads) 
var triangles = 12 * 150000; 

var geometry = new THREE.BufferGeometry(); 
geometry.attributes = { 

    position: { 
     itemSize: 3, 
     array: new Float32Array(triangles * 3 * 3), 
     numItems: triangles * 3 * 3 
    }, 

    normal: { 
     itemSize: 3, 
     array: new Float32Array(triangles * 3 * 3), 
     numItems: triangles * 3 * 3 
    }, 

    color: { 
     itemSize: 3, 
     array: new Float32Array(triangles * 3 * 3), 
     numItems: triangles * 3 * 3 
    } 
} 

positions = geometry.attributes.position.array; 
normals = geometry.attributes.normal.array; 
colors = geometry.attributes.color.array; 

Se mi muovo un cubo, non comparirà essere spostato fino a quando lo faccio :

geometry.attributes.position.needsUpdate = true; 

Ciò causa l'interruzione di FPS durante l'aggiornamento. C'è un altro modo per farlo? Sembra un po 'inutile quando cambio solo un cubo (12 triangoli/36 vertici). Anche se potrebbe essere - Non ho controllato cosa fa effettivamente lo needsUpdate. Indovinando invia di nuovo la matrice allo shader.

Stavo pensando che potrei dividere la geometria in BufferGeometries separati più piccoli, ma non sono sicuro che ciò aiuterebbe le prestazioni nel complesso. Da quello che ho capito, più geometrie = meno FPS.

Se qualcuno ha qualche idea su come farei questo, sarebbe apprezzato! :) Oltre al problema di aggiornamento, BufferGeometry sembra essere esattamente ciò di cui ho bisogno. Grazie!

risposta

7

Ho avuto lo stesso problema con un BufferGeometry molto grande durante l'aggiornamento di alcuni vertici in esso.

Una soluzione è utilizzare _gl.bufferSubData anziché _gl.bufferData per aggiornare solo una parte del buffer. (Tre j utilizza solo _gl.bufferData).

Quindi, se si aggiornano le posizioni si farà:

// creare una visualizzazione dei dati per aggiornare dall'indice offsetSub a offsetSubEnd

var view = geometry.attributes.position.array.subarray(offsetSub, offsetSubEnd);

// Assorbire il buffer per le posizioni (ottenere il contesto gl con webglrenderer)

_gl.bindBuffer(_gl.ARRAY_BUFFER, geometry.attributes.position.buffer);

// inserire il nuovo valori in buon indice nel buffer di gpu (offsetGeometry è nel byte)

_gl.bufferSubData(_gl.ARRAY_BUFFER, offsetGeometry,view);

Si noti che questa soluzione può essere più lento se si cambia una gran parte dei vertici del buffer rispetto al _gl.bufferData.

6

A partire da r71 tre supporti bufferSubData.

Utilizzare un DynamicBufferAttribute, (o semplicemente impostato updateRange correttamente)

var positionAttr = geometry.attributes.position 
// if not using DynamicBufferAttribute initialize updateRange: 
// positionAttr.updateRange = {}; 
positionAttr.updateRange.offset = 0; // where to start updating 
positionAttr.updateRange.count = 1; // how many vertices to update 
positionAttr.needsUpdate = true; 
Non
+2

sicuro quale versione è stato cambiato, ma come di 'r81' questo è stato unito in (https [BufferAttribute'']: // github.com/mrdoob/three.js/blob/r81/src/core/BufferAttribute.js#L27). – Jay

Problemi correlati