2016-05-05 21 views
1

多くの個々のオブジェクトを持つ大きなThree.jsシーンを扱います。 25kから50kのシーンで終わるのは簡単です。Object3Dインスタンス。はい、これは大変ですが、現在のところ、この番号を簡単に減らす方法はありません。すべてのオブジェクトを削除してそのようなシーンを消去するには、通常約2分かかります。これは、それぞれの要素を個別に​​で削除し、すべての要素を最初に収集してscene.remove(element1, element2, ...);を呼び出す場合です。我々はまた、シーン全体のインスタンスを置き換えようとしましたが、役に立たなかった:それはまだ遅かったです。Three.jsシーンから多くのオブジェクトを削除するslow

異なるグラフィックスカード間にいくつかの違いがあり、これはグラフィックスカードから削除する必要があると思われるバッファジオメトリを多く使用していることが原因であると思われます。

オブジェクトの削除中にブラウザがブロックされているため、この期間はウェブサイトが使用できなくなります。オブジェクトの削除のパフォーマンスを向上させる方法や、非ブロック化する方法がありますか(個々の要素を削除する場合はsetTimeout()はありません)。

これが簡略化で問題(最初のフレームの後に除去50Kキューブを使用して、私たちのオブジェクトのいくつかははるかに複雑です)を示しています。単一のメッシュをマージし、削除メッシュ試してみてくださいhttp://jsfiddle.net/ua2mg5ty/

+0

む〜。おそらく 'InstancedBufferGeometry'を使用しているはずです。たとえば、[this](http://threejs.org/examples/webgl_buffergeometry_instancing.html)および[this](http://threejs.org/examples/webgl_buffergeometry_instancing_dynamic.html)を参照してください。 – WestLangley

+0

ポインタありがとう!私が間違っていない場合、 'InstanceBufferGeometry'を使うことは、個々のオブジェクトインスタンスが似ていることを意味します。私たちは、互いに非常に異なる多くの大きなニューロンを表示します。それらは現在、通常の 'Geometry'インスタンスを使って' LineSegments'に基づいています。私は 'InstanceBufferGeometry'を使って1つの線分だけを保存し、正しい位置に個々の線分をインスタンス化するためにオフセット配列を使うことができると思います。これは理にかなっていますか? – tomka

+0

おそらく。または 'BufferGeometry'を使用してください。通常のジオメトリを避けます。オブジェクトを削除するときは 'dispose()'を呼び出すように注意してください。 – WestLangley

答えて

4

を。

http://jsfiddle.net/2t8j5caj/

除去時間:0.13500000000021828ms、時間をレンダリング:3.6000000000012733ms

var mesh = new THREE.Mesh(singleGeometry, material); 
for (var i = 0; i < nCubes; i++) { 
    var box = new THREE.BoxGeometry(1, 1, 1); 
    var cube = new THREE.Mesh(box); 
    cube.position.x = (Math.random() - 0.5) * 5; 
    cube.position.y = (Math.random() - 0.5) * 5; 
    cube.position.z = (Math.random() - 0.5) * 5; 
    cube.scale.set((Math.random() - 1 * cubeSize), (Math.random() - 1 * cubeSize), (Math.random() - 1 * cubeSize)) 
    cube.updateMatrix(); 

    singleGeometry.merge(cube.geometry, cube.matrix); 
} 
var mesh = new THREE.Mesh(singleGeometry, material); 
scene.add(mesh); 
+0

ありがとう、これは別の良い提案です。論理オブジェクト(私の場合のニューロン)には、個別に表示/非表示し、異なるシェーダを適用し、異なるマウスピッキング動作を持たせたい複数のメッシュが含まれています。 1つの論理オブジェクト内のすべてのメッシュをマージすると、おそらくすべてが緩んでしまいます。 – tomka

+0

乾杯。可能であれば、マージ前にシェーダを特定の面に適用し、特定の面を表示/非表示にする特定のマテリアルを変更することができます。レイピッキングはすでにフェイスベースです。離散的なメッシュオブジェクトではなく、メッシュをフェイスのコレクションと考えてください。後者は自由のように感じられるほうが好ましいですが、JSは単なるスレッドで大きなセットを処理できません。また、顔や頂点は、3人の開発者が意図しなかったプロパティを与えることができるクラスオブジェクトであることを覚えておいてください。 3つはプロトタイプクラスベースです。 3つのクラスを適切に拡張しても、クラスの完全性は損なわれません。 – Radio

+1

申し訳ありませんが、私はこの回答を受け入れることを忘れました。私はあなたが提案したことをやめてしまいましたが、私の質問に対するWestLangleyのコメントだけでなく、答えが正しい方向に私を導きます:手動でInstanceBufferGeometryオブジェクトとシェーダを作成します。これにより、削除に数ミリ秒しかかかりません。 – tomka

関連する問題