本文介绍了imageData CanvasPixelArray是否可直接用于画布WebGL上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Three.js将3D模型绘制到简单DOM元素上方的webgl画布渲染器上,我需要在它们之间进行碰撞检测.我当前的工作方法是使用renderer.domElement.toDataURL(),将其作为imageData对象加载,然后将其绘制到单独的2D画布上下文中,然后拉出getImageData()像素数组,并使用这个很棒的像素碰撞功能.

I'm using Three.js to draw 3D models onto a webgl canvas renderer above simple DOM elements, and I need to do collision detection between them. My currently working method is to use renderer.domElement.toDataURL(), load this as an imageData object then draw this onto a separate 2D canvas context, then pull the getImageData() pixel array and iterate through using this awesome pixel collision function.

这很慢, ,将我的帧速率降低到几乎无法播放的〜5-8 FPS.如果不运行此命中检测,我将获得大约40-50 FPS.

This is incredibly slow, and pulls my frame rate down to a nearly unplayable ~5-8 FPS. Without running this hit detection I get about 40-50 FPS.

我最好的猜测是,速度变慢是难以置信的 toDataURL()-> load image-> drawImage()-> getImageData().

My best guess is that the slowdown is the incredibly unwieldy toDataURL()->load image->drawImage()->getImageData().

我的问题变成:是否有更好的方法来访问WebGL画布上可用的展平2D像素数据?还是也许有一种更好的无视差外推3D对象坐标的方法?老实说,任何比我目前做的更快的碰撞检测方法都是非常有用的.

My question becomes: Is there a better way to access the flattened 2D pixel data available on the WebGL canvas? or perhaps a better method of extrapolating my 3D object coordinates without parallax? Honestly, any way to get some kind of collision detection faster than I'm currently doing it will be immensely useful.

编辑:WebGL上下文.readPixels()对我来说很好 ,并且与我之前的文章相比非常快.尽管应注意,与常规图像像素数据阵列相比,数据阵列从上到下都是镜像的.我只是简单地翻转了碰撞常规的Y值检查并使其生效,尽管其他人可能会以更棘手的方式被绊倒.祝你好运!

EDIT: the WebGL context.readPixels() works great for me, and is super fast compared to my previous kludge. Though it should be noted that the data array is mirrored top-to-bottom as compared with a regular image pixel data array. I simply flipped my collision routine Y value check and got this to work, though others may get tripped up in trickier ways. Good luck!

推荐答案

您可以使用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现在包含以[R, G, B, A, R, G, B, A...]布局的无符号字节(0-255)的场景像素数据,应该与getImageData相同,但成本要低得多.

pixelData now contains the scene's pixel data as unsigned bytes (0-255) laid out as [R, G, B, A, R, G, B, A...] Should be the same data as getImageData but at a much lower cost.

[ ]

我忘记提及了,如果您要这样做,您将希望使用preserveDrawingBuffer选项创建WebGL上下文,如下所示:

I forgot to mention that if you're going to be doing this, you'll want to create your WebGL context with the preserveDrawingBuffer option, like so:

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

这可以防止WebGL的内部工作在到达缓冲区之前清除缓冲区(这将导致您读取大量空白像素).启用此选项可能会减慢渲染速度,但加载速度仍应比5-8 FPS快! :)

This prevents WebGL's inner workings from clearing the buffer before you get to it (which would result in you reading a whole lot of empty pixels). Enabling this option has the potential to slow down your rendering, but it should still be loads faster than 5-8 FPS! :)

这篇关于imageData CanvasPixelArray是否可直接用于画布WebGL上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 02:42