【问题标题】:Quickest way to render a Uint8Array to a Canvas将 Uint8Array 渲染到 Canvas 的最快方法
【发布时间】:2017-03-06 12:02:59
【问题描述】:

我收到了带有 RGBA 值的Uint8Array,以及图像的哪些部分已更新的一些信息。将这个原始位图信息渲染回画布的最快方法是什么?我一直在使用 2D 渲染上下文手动循环数组并设置像素信息,但这非常慢:

let imageData = new ImageData(1920, 1080);
for (var i=0;i < args.frameBuffer.length; i+=4) {
    imageData.data[i]   = args.frameBuffer[i];
    imageData.data[i+1] = args.frameBuffer[i+1];
    imageData.data[i+2] = args.frameBuffer[i+2];
    imageData.data[i+3] = args.frameBuffer[i+3];
}
context.putImageData(imageData, 0, 0, args.dirtyX, args.dirtyY, args.dirtyWidth, args.dirtyHeight);

什么是更有效的方法来做到这一点? WebGL 会比 2D 上下文更高效吗?原生还是通过 Three.js 之类的东西?

【问题讨论】:

  • 看看textures。特别是 texImage2D 方法。
  • 要在类型数组之间移动数据,您可以使用imageDataTo.data.set(imageDataFrom.data) 要复制部分数据(矩形),请使用setsubArray 移动行。对于每一行(imageData 是 id)idTo.data.set(idFrom.data.subArray((yFrom*idFrom.width+xFrom)*4,width),(yTo*idTo.width+xTo)*4) 如果您需要检查每个像素,您可以创建一个 Uint32Array 以使用data32 = new Uint32Array(imageData.data.buffer) 在一次读取/写入中处理一个像素@ 注意小/大端开始发挥作用。画布也是一个图像,因此您可以将context.drawImage(canvasFrom,... 从画布渲染到画布

标签: javascript canvas webgl


【解决方案1】:

您可以使用 gl.TexSubImage2D 来更新纹理,然后将您的纹理整体 blit。但是 TexSubImage2D 存在性能问题,因为它必须等待上一次渲染完成才能更新下一帧的纹理。

更好的方法是对 webgl 使用 preserveDrawingBuffer 位,然后使用 TexImage2D 以循环方式使用两个纹理。要仅渲染脏区域,您需要根据脏坐标为 DrawArrays 设置顶点数据。

WebGL 仍然需要大量复制数据,但也许这些复制路径比 putImageData 优化得更好。但是 webgl 可能会变慢存在严重的危险,因为驱动程序经常针对纹理图像是静态的并用于多个渲染的用例进行优化。这使得渲染速度更快,但上传纹理数据更慢。

为了解决代价高昂的纹理上传问题,OpenGL 有多个扩展支持快速图像上传,但渲染速度有点慢。太糟糕了,这些扩展对 webgl 不实用。

但是你的复制循环看起来很像你每次都接收整个帧缓冲区,即使它只是部分更新。

如果你能做类似的事情

let imageData = new ImageData(args.frameBuffer, args.dirtyWidth, args.dirtyHeight);
context.putImageData(imageData, args.dirtyX, args.dirtyY);

当然你当前的界面可以重复

let imageData = new ImageData(args.frameBuffer, 1920, Math.floor((args.frameBuffer.length + 4*1919)/(4*1920)));
context.putImageData(imageData, 0,0, args.dirtyX, args.dirtyY, args.dirtyWidth, args.dirtyHeight);

【讨论】:

  • 感谢您指出我正在使用整个 frameBuffer。这已经大大加快了速度。
猜你喜欢
  • 1970-01-01
  • 2013-11-07
  • 2021-12-29
  • 1970-01-01
  • 2014-03-19
  • 1970-01-01
  • 2012-12-06
  • 2014-05-21
  • 2012-09-21
相关资源
最近更新 更多