4

Three.jsを使用して、単純なDOM要素の上にあるwebglキャンバスレンダラーに3Dモデルを描画していますが、それらの間の衝突検出を行う必要があります。私の現在の方法は、renderer.domElement.toDataURL()を使用し、これをimageDataオブジェクトとしてロードしてから、これを別の2Dキャンバスコンテキストに描画し、getImageData()ピクセル配列をプルして、この素晴らしいピクセルコリジョン関数を使用して反復処理することです。

これは非常に遅く、フレームレートをほぼ再生不可能な約5〜8FPSまで下げます。このヒット検出を実行しないと、約40〜50FPSになります。

私の推測では、速度の低下は信じられないほど扱いにくいtoDataURL()-> load image-> drawImage()-> getImageData()です。

私の質問は次のようになります。WebGLキャンバスで利用可能なフラット化された2Dピクセルデータにアクセスするためのより良い方法はありますか?または、視差なしで3Dオブジェクトの座標を外挿するためのより良い方法はありますか?正直なところ、私が現在行っているよりも速くある種の衝突検出を取得する方法は、非常に便利です。

編集:WebGL context.readPixels()は私にとって素晴らしい働きをし、以前のクラッジと比較して超高速です。ただし、データ配列は、通常の画像ピクセルデータ配列と比較して上から下にミラーリングされていることに注意してください。コリジョンルーチンのY値チェックを反転して、これを機能させましたが、他の人はトリッキーな方法でつまずく可能性があります。幸運を!

4

2 に答える 2

4

あなたが使用することができますgl.readPixels

// Render your scene first then...
var left = 0;
var top = 0;
var width = canvas.width;
var height = canvas.height;
var pixelData = new Uint8Array(width * height * 4);
gl.readPixels(left, top, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);

pixelDataには、シーンのピクセルデータが符号なしバイト(0〜255)として含ま[R, G, B, A, R, G, B, A...]れるようになりました。これは、同じデータである必要がありますgetImageDataが、はるかに低コストです。

[編集: ]

preserveDrawingBufferこれを行う場合は、次のようなオプションを使用してWebGLコンテキストを作成する必要があることを忘れました。

var gl = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true});

これにより、WebGLの内部動作が、バッファに到達する前にバッファをクリアするのを防ぎます(これにより、多くの空のピクセルを読み取ることになります)。このオプションを有効にすると、レンダリングが遅くなる可能性がありますが、それでも5〜8FPSよりも高速にロードされるはずです。:)

于 2012-02-28T07:37:58.413 に答える
0
 renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer:true });



 var gl = renderer.getContext()
 var buf = new Uint8Array(200 * 200 * 4);
 gl.readPixels(0, 0, 200, 200, gl.RGBA, gl.UNSIGNED_BYTE, buf);


console.log(buf);

これは正常に機能します。

于 2013-08-11T15:20:46.517 に答える