我使用Three.js在简单DOM元素之上的webgl画布渲染器上绘制3D模型,并且需要在它们之间进行碰撞检测。我目前的工作方法是使用renderer.domElement.toDataURL(),将其作为imageData对象加载,然后将其绘制到单独的2D画布上下文中,然后提取getImageData()像素数组并使用这个令人敬畏的像素碰撞功能进行迭代。
这是难以置信的慢,并把我的帧速率降低到一个几乎不可播放的5-8 FPS。不运行这个命中检测,我得到约40-50 FPS。
我最好的猜测是,增长放缓的原因是toDataURL()->load图像->drawImage()->getImageData()极其笨拙。
我的问题是:是否有更好的方法来访问WebGL画布上可用的平面2D像素数据?还是一种不用视差外推三维物体坐标的更好方法?老实说,任何比我现在做的更快的碰撞检测的方法都是非常有用的。
编辑:WebGL context.readPixels()对我来说非常有用,而且与我之前的拼图相比速度非常快。尽管应该注意到,与常规的图像像素数据数组相比,数据数组是自上而下的镜像。我只是简单地翻转了我的碰撞例程Y值检查,并使这个工作,虽然其他人可能会被绊倒在更棘手的方式。祝好运!
发布于 2012-02-28 07:37:58
您可以使用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
相同,但成本要低得多。
编辑:
我忘记提到,如果要这样做,您需要使用WebGL选项创建您的preserveDrawingBuffer
上下文,如下所示:
var gl = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true});
这将阻止WebGL的内部工作在到达缓冲区之前清除它(这将导致读取大量空像素)。启用此选项可能会减慢呈现速度,但其加载速度仍应快于5-8 FPS!)
发布于 2013-08-11 15:20:46
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);
这个很好用。
https://stackoverflow.com/questions/9470043
复制相似问题