imageData CanvasPixelArray是否可直接用于画布WebGL上下文?

时间:2012-02-27 18:16:56

标签: collision-detection webgl three.js hit

我正在使用Three.js将3D模型绘制到简单DOM元素上方的webgl画布渲染器上,我需要在它们之间进行碰撞检测。我目前使用的方法是使用renderer.domElement.toDataURL(),将其作为imageData对象加载,然后将其绘制到单独的2D画布上下文中,然后拉出getImageData()像素数组并使用this awesome pixel collision function进行迭代。 / p>

难以置信 慢,并将我的帧速率降低到几乎无法播放的~5-8 FPS。如果没有运行此命中检测,我可以获得大约40-50 FPS。

我最好的猜测是,减速是非常笨拙的 toDataURL() - >加载图像 - > drawImage() - > getImageData()

我的问题变成了:是否有更好的方法来访问WebGL画布上可用的拼合2D像素数据?或者更好的方法是在没有视差的情况下推断我的3D对象坐标?老实说,任何能比我目前更快地获得某种碰撞检测的方法都非常有用。

编辑:WebGL context.readPixels()对我来说非常,与我之前的kludge相比,速度非常快。虽然应该注意,与常规图像像素数据阵列相比,数据阵列从上到下是镜像的。我简单地将我的碰撞例程Y值检查翻了下来并使其工作,尽管其他人可能会以棘手的方式绊倒。祝你好运!

2 个答案:

答案 0 :(得分: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-8 FPS! :)

答案 1 :(得分: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);

这很好。