允许更多的 WebGL 上下文

Allowing more WebGL contexts

我目前正在开发一个包含项目列表的网站。每个项目都有一个缩略图,我正在使用 PixiJS 在所有项目上添加着色器效果。问题是列表中的项目超过 16 个,所以我收到以下错误:

WARNING: Too many active WebGL contexts. Oldest context will be lost.

有没有办法增加这个限制?我不能在 WebGL 上制作整个页面,而且使用非常有限(没有交互,精简版效果),我认为更多的 WebGL 上下文不会使页面延迟或其他问题。

不是不可能增加限制。 (好吧,你可以编写自己的浏览器)。

要列出项目,您可以使用此问答中的解决方案

详见this article for WebGL and this article for three.js

这里有 3 个解决方案。

  1. (最快)使用覆盖页面的单个 WebGL canvas。使用占位符元素来标记要绘制内容的位置。遍历那些调用 element.getBoundingClientRect 的元素,并使用视口和剪刀设置在那些地方绘制,只绘制可见的(有些可能在屏幕外,不需要绘制)。这是上面链接中显示的解决方案。

  2. 使用单个屏幕外 WebGL canvas。在您的页面中放置 2D canvases。将每个项目绘制到屏幕外 canvas 并使用 drawImage 将其绘制到正确的 2D canvas。这个解决方案稍微灵活一些,因为 2D canvas 元素可以更自由地设置样式,但它比以前的解决方案慢并且使用更多内存。

    注意:最好将 WebGL canvas 设置为最大 2D canvas 的大小,然后对于每个 2D canvas,将 gl.viewport 设置为大小该 2D canvas 然后使用 drawImage 的完整形式 select WebGL 的一部分 WebGL 的正确大小部分 canvas 绘制当前的 2D canvas。我认为调整 canvas 的大小是一项繁重的操作。换句话说是这样的:

    for each 2D canvas
       webgl canvas size = max(webgl canvas size, 2D canvas size) // for each dimension
       gl.viewport(0, 0, 2D canvas size);
       draw scene for canvas
       ctx.drawImage(
           0, 0, 2D canvas size, 
           0, webgl canvas height - 2d canvas height, 2D canvas size)
    
  3. 使用您可以自己实现的虚拟 webgl 上下文或 use a library。不推荐(最慢),但这是一个快速的解决方案。

注意:拥有多个上下文不是推荐的解决方案。纹理、顶点和着色器可以 在 WebGL 上下文之间共享。这意味着如果您在 2 个或更多上下文中使用相同的图像,则必须为每个上下文将其加载到内存中一次。类似地,对于使用着色器的每个上下文,它必须针对每个上下文进行编译和链接。换句话说,使用多个上下文会占用更多内存并显着增加启动时间。

不幸的是,由于您将问题同时标记为 WebGL 和 pixi.js,因此此答案可能与您无关。我不知道这在 pixi.js 中是否可行。我没有看到任何文档来建议如何有效地做到这一点。

如果您控制正在使用的浏览器,还有一个替代解决方案。 Chrome 有以下命令行开关来控制活动上下文的最大数量。

--max-active-webgl-contexts=<number>

您可以使用此参数设置快捷方式,以获得 Chrome 限制较少的浏览器。