WebGL - 发送数组缓冲区 VS 将图像/画布/位图从 CPU 发送到 GPU

Posted

技术标签:

【中文标题】WebGL - 发送数组缓冲区 VS 将图像/画布/位图从 CPU 发送到 GPU【英文标题】:WebGL - Sending arraybuffer VS sending image/canvas/bitmap from CPU to GPU 【发布时间】:2021-01-24 05:03:33 【问题描述】:

我正在编写一个虚拟纹理应用程序,我正在使用 16384*16384(宽度和高度)的纹理。

所以,最初我创建了一个 16384/16384(宽度/高度)的空纹理。

gl.texImage2d(...., width, height, gl.RGBA, ..., null)

我有多个 1024*1024 的 jpeg 图像,因此能够正确填充图像而不会出现任何问题。 但我看到的是当我使用 gl.texSubImage2D(.........., imageelement) 需要 10-30 毫秒

但如果我使用gl.texSubImage2D(.........., arraybuffer),则需要0-2毫秒。

我已经完成了这个link 并尝试更改我的应用程序中的参数,但没有性能提升。

在使用 gl.texImage2D 或 gl.texSubImage2d 获取图像(jpgs/bmps/pngs)或数组缓冲区(Uint8Array/Uint16Array)之后,WebGL 在 GPU 中究竟发生了什么。 是否涉及任何需要额外时间的转换。

【问题讨论】:

【参考方案1】:

哪个浏览器?

浏览器做什么取决于浏览器。在最坏的情况下,它还没有解码图像。换句话说,它仍然是压缩的 JPG,而不是未压缩的位图。

假设它是位图,您向浏览器询问 RGBA/UNSIGNED_BYTE,但它可能将图像存储为 RGB/UNSIGNED_BYTE,因此它必须将整个图像或其子矩形从一种格式转换为另一种格式,这意味着分配空间来做,然后做,然后调用 texImage2D 或 texSubImage2D,然后释放内存

在最好的情况下,图像已经在 GPU 中,浏览器可以使用着色器将该图像的一部分渲染到纹理中,从而有效地模拟 texImage2D/texSubImage2D。我知道 Chrome 有办法做到这一点。我相信,至少截至 2020 年 9 月,Firefox 和 Safari 都没有。即使一个或两个都有路径可以做到这一点,他们对于是否可以使用该路径肯定有不透明的条件。 ImageBitmap 应该有助于使这些条件更有可能与 Image 不太可能。

【讨论】:

我使用的是谷歌浏览器,我也在探索 gl.compressedTexture2D 但它只需要 arraybuffer,不允许使用图像/位图/画布 你的机器、操作系统、gpu是什么? 它是 i5、windows、intel 520 HD 这只是一个猜测,如果有一条快速路径,它不会被该组合采用。在任何情况下,您至少应该确保您使用的是ImageBitmap,而不是Image。但是,如果您看不出有什么不同,我没有任何其他建议。 我们是否有任何替代技术可以更快地执行此操作?例如:WebGPU

以上是关于WebGL - 发送数组缓冲区 VS 将图像/画布/位图从 CPU 发送到 GPU的主要内容,如果未能解决你的问题,请参考以下文章

WebGL - 从渲染缓冲区读取像素数据

WebGL纹理颜色原理

发送“画布”生成的图像,不保存到文件

readPixels 函数返回未修改的纹理

WebGL 纹理颜色原理

如何在不模糊的情况下拉伸 WebGL 画布? “图像渲染”样式不起作用