Allowing more WebGL contexts

我是研究僧i 提交于 2020-05-29 11:48:08

问题


I'm currently working on a website with a list of items. Each item has a thumbnail, and I'm adding a shader effect on all of them using PixiJS. The problem is that there's more than 16 items on the list, so I'm getting the following error :

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

Is there a way to increase this limit ? I can't make the whole page on WebGL, and the usage is so limited (no interaction, lite effect) that I think more WebGL contexts will not make the page laggy or something.


回答1:


Not it is not possible to increase the limit. (well you could write your own browser).

To make a list of items you can use solutions like in this Q&A

Multiple WebGL models on the same page

which are detailed in this article for WebGL and this article for three.js

Here are 3 solutions.

  1. (fastest) Use a single WebGL canvas that covers the page. Use place holder elements to mark where you want to draw things. Loop through those elements calling element.getBoundingClientRect and use the viewport and scissor settings to draw in those places, only drawing the ones that are visible (some may be offscreen and don't need to be drawn). This is the soution shown in the links above.

  2. Use a single offscreen WebGL canvas. Put 2D canvases in your page. Draw each item to the offscreen canvas and use drawImage to draw it to the correct 2D canvas. this solution is slightly more flexible since the 2D canvas elements can be more freely styled but it's slower than the previous solution and uses more memory.

    Note: it's probably best to make the WebGL canvas the size of the largest 2D canvas, then for each 2D canvas, set gl.viewport to the size of that 2D canvas and then use the full form of drawImage to select a portion of the WebGL the correct size portion of the WebGL canvas to draw the current 2D canvas. Resizing a canvas is a heavy operation I believe. In other words something like:

    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. Use a virtual webgl context which you can implement on your own or use a library. Not recommended (slowest) but it is a quick solution.

Note: having multiple contexts is not a recommended solution. Textures, vertices, and shaders can not be shared between WebGL contexts. That means if you use the same image in 2 or more contexts it has to be loaded into memory once for each context. Similarly for each context a shader is used it has to be compliled and linked for each context. In other words using multiple contexts uses more memory and increases startup time significantly.

Unfortunately since you tagged your questions both WebGL and pixi.js this answer is probably irrelevant to you. I have no idea if this is possible in pixi.js. I see no documentation to suggest how to do it efficiently.




回答2:


There is an alternative solution in case you control the browser being used. Chrome has the following command line switch to control the maximum amount of active contexts.

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

You can setup a shortcut with this argument to have a Chrome browser that's less limited.



来源:https://stackoverflow.com/questions/59140439/allowing-more-webgl-contexts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!