2013-07-01 88 views
5

我正在使用BufferGeometry繪製組成地形的數千個立方體,但如果需要更改其中一個立方體的位置,則很難找出如何更新幾何體。例如,我有這樣的代碼來初始化我的幾何圖形:(我正在做的事情的this example的更新版本我的測試)如何快速更新大型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; 

如果我提出一個立方體,它不會出現移動,直到我做:

geometry.attributes.position.needsUpdate = true; 

這使得FPS下降它的更新時間。有另外一種方法可以做到這一點嗎?當我只改變一個立方體時(12個三角形/ 36個頂點)似乎有點不必要。雖然它可能是 - 我沒有檢查needsUpdate實際上做了什麼。猜測它再次將數組發送到着色器。

我在想我可以將幾何分割成單獨的較小的BufferGeometries,但我不確定這是否會對整體性能有所幫助。據我所知,更多的幾何形狀=更少的FPS。

如果有人有任何想法我會怎麼做,這將不勝感激! :)除了更新問題,BufferGeometry似乎正是我所需要的。謝謝!

回答

7

我在更新一些非常大的BufferGeometry時遇到了同樣的問題。

解決方法是使用_gl.bufferSubData而不是_gl.bufferData來更新緩衝區的一部分。 (三個js只使用_gl.bufferData)。

所以,如果你更新的位置,你會做什麼:

//創建數據的視圖,從指數offsetSub更新到offsetSubEnd

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

//綁定的位置緩衝區(得到與webglrenderer的GL上下文)

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

//將新在GPU緩衝良好的指數值(offsetGeometry是字節)

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

請注意,如果你改變相比_gl.bufferData緩衝區頂點的很大一部分該解決方案可以慢。

6

截至r71 threejs支持bufferSubData

使用一個DynamicBufferAttribute,(或只設置updateRange正確)

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; 
+2

不知道哪個版本,它改變了,但作爲'r81'這已經合併到['BufferAttribute'(https://開頭github.com/mrdoob/three.js/blob/r81/src/core/BufferAttribute.js#L27)。 – Jay