2013-07-01 15 views
5

私は地形を構成する何千もの立方体を描画するためにBufferGeometryを使用していますが、キューブの1つの位置を変更する必要がある場合、ジオメトリを更新する方法を見つけるのは難しいです。例えば、私は私のジオメトリを初期化するには、このコードを持っている:私はまで私は、キューブを移動した場合大きな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; 

(私はthis exampleの更新バージョンに私のテストをやっている)、移動することが表示されません。 :

geometry.attributes.position.needsUpdate = true; 

これにより、更新中にFPSがドロップされます。私はこれを行うことができる別の方法はありますか? 1つのキューブを変更するだけでは少し不必要なようです(12三角形/ 36頂点)。それはかもしれませんが、私は実際に何をneedsUpdateがチェックしていません。それを推測すると、アレイは再びシェーダに送られます。

ジオメトリを別々の小さなBufferGeometriesに分割できると思っていましたが、全体的なパフォーマンスに役立つかどうかはわかりません。私が理解しているところから、より多くの幾何学的なものはFPS以下です。

誰かが私がこれをどうやって行うか考えているなら、それは分かります! :)更新の問題のほかに、BufferGeometryは私が必要とするものと正確に思われる。ありがとう!

答えて

7

いくつかの頂点を更新する際に、非常に大きなBufferGeometryで同じ問題が発生しました。

解決策は、_gl.bufferDataの代わりに_gl.bufferSubDataを使用して、バッファの一部だけを更新することです。 (3つのjは_gl.bufferDataのみを使用します)。あなたがポジションを更新した場合

だからあなたが行います。

は//

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

が//ポジションのためのバッファをバインドoffsetSubEndするインデックスoffsetSubから更新するために、データのビューを作成します(新しい挿入//

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

)webglrendererとGLコンテキストを取得あなたは_gl.bufferDataに比べバッファ頂点の大部分を変更する場合は、このソリューションが遅くなることができ、GPUバッファ内の良好な指標での値(offsetGeometryがバイトである)

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

注意。

6

r71から3jsはbufferSubDataをサポートします。

使用DynamicBufferAttributeは、それが変更されたバージョンを確認してください

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

ないが、これは[ 'BufferAttribute'](HTTPSにマージされたr81''のように(あるいは単に正しくupdateRangeを設定):// github.com/mrdoob/three.js/blob/r81/src/core/BufferAttribute.js#L27)。 – Jay

関連する問題