如何使用WebGL异步加载图像,创建纹理,渲染和保存图像?

时间:2011-09-02 18:24:18

标签: javascript asynchronous webgl

我正在尝试编写一个使用非常大的纹理的应用程序。这个想法是你在实时修改着色器时处理纹理的缩放版本,完成后应用程序会将你的更改应用到原始的未缩放(大)纹理。问题是分析显示如下内容:

  • img.src = filename(500ms)
  • texImage2d(...)(1500ms)
  • bind / rendering(100ms)
  • readPixels(300ms)
  • 放入画布(1000毫秒)
  • 将画布保存到文件(300毫秒)

基本上这意味着当保存较大的未缩放纹理时,浏览器会锁定近四秒钟,而用户无法执行任何操作。是否可以异步执行此操作以使浏览器保持响应?它需要在javascript和客户端完成,因为我使用的是本地文件(HTML5文件/文件系统)。

网络工作者听起来是个好主意,但他们无法访问DOM,因此我无法使用浏览器的图像加载和保存功能,并且他们无法访问WebGL上下文,因此他们无法调用texImage2d这需要花费最多的时间。

由于图像的大小和数量,当页面最初加载时,我无法将它们全部作为纹理加载到内存中。

是否可以采取任何措施使其对用户更具响应性?我希望他们能够在前一个图像渲染时继续处理下一个图像。

2 个答案:

答案 0 :(得分:2)

图片加载应该在后台进行,你不会知道它的进展,但你可以使用texSubImage2D逐步上传纹理。这可能会花费更长的时间,但你应该能够给用户一些反馈并回应其他事件。

此外,您可以直接将webgl画布绘制到画布2D中。 drawImage()将图像,视频和画布(2D或webgl)元素作为参数。这应该几乎立即发生并节省大约1300毫秒。

答案 1 :(得分:0)

这个问题很旧,但是对于其他发现它的人来说,这里是一些更新的信息

  • 您可以考虑使用自2019年1月以来一直在Chrome中发货的OffscreenCanvas。不幸的是,它没有在其他任何地方的ATM上发货

  • 这3个同步步骤

    readPixels (300ms)
    Put into canvas (1000ms)
    Save canvas to file (300ms)
    

    可以变成1个异步步骤

    gl.canvas.toBlob((blob) => {
      const url = URL.createObjectURL(blob);
      // url is now something you can give the user to download
    });
    
  • 要渲染非常大的图像(例如16k x 16k),可以渲染较小的部分并将它们组合成较大的图像。

    这里有一个图书馆:https://greggman.github.io/dekapng/