WebGL HTML5 游戏的纹理缓存溢出
Texture cache overflow for WebGL HTML5 game
我正在创建一个 HTML5 网络冒险游戏并使用 Tiled 制作地图。
即使使用 Texture Packer,我似乎也超出了纹理单元的最大缓存,因为我收到错误
Texture cache overflow: 16 texture units available
WebGL Stats shows the limit is 16 for ~70% of devices. My browser, as shown here,支持16个纹理单元:
在游戏中,我打开 Chrome 控制台查看 WebGL 规格:
WebGL2RenderingContext.MAX_TEXTURE_IMAGE_UNITS
= 34930
WebGL2RenderingContext.MAX_VERTEX_TEXTURE_IMAGE_UNITS
= 35660
WebGL2RenderingContext.MAX_COMBINED_TEXTURE_IMAGE_UNITS
= 35661
这有点令人困惑,因为 this article 显示输出应该在 0-10 范围内,而不是 30,000 范围内:
maxTextureUnits = 8
maxVertexShaderTextureUnits = 4
maxFragmentShaderTextureUnits = 8
我的问题:
- 如何确定打包纹理图集中的哪些图像导致了问题?即,我如何检查总纹理?
- 是否可以强制提高缓存限制?
检查这些值的方法是
const maxFragmentShaderTextureUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
const maxVertexShaderTextureUnits = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
const maxTextureUnits = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
此外,这些值与您可以在单个着色器中访问多少纹理有关,而不是您总共可以拥有多少纹理。
它们也与"cache"
无关
在您的情况下,您可能希望将纹理组合成一个纹理图集(一个纹理包含所有图块)。
Here's some code that does that。
它加载一个平铺的 json 文件,然后加载所有引用的图像,然后创建一个 2D canvas 并将每个图像的图块复制到 canvas,将地图中的图块重新映射到比赛。完成后,它使用 canvas 作为图块纹理的来源。通常我会离线执行此操作,但很高兴能够点击 "reload" 来查看我在运行时留下的新地图。
在同一个库中 a shader that draws tilemaps including flipped and rotated tiles. In other words, to draw a tiled map it's one draw call per layer and only 2 textures are used. One texture holds the tile images (the texture created above). Another texture holds a layer of a tiled map. The shader reads the tiled map texture and uses that to draw the correct tile from the tile image texture. You can see an explanation of this technique in this article
顺便说一句:带有平铺加载程序的库也有 a shader that can selectively adjust the hue of a sprite. The library was used with a few games, for example this game
- How can I determine which images in my packed texture atlas are causing the issues? I.e., how can I check the total textures?
你管理纹理,而不是 WebGL,所以如果你想知道你使用了多少,添加一些代码来计算它们。
- Is it possible to force a higher cache limit?
不,但正如我上面所说,这与任何缓存无关。
我的猜测是您正在使用某个库,或者您自己的代码正在生成一个着色器,并且您正在向它添加越来越多的纹理,因此着色器生成器生成一个使用过多纹理的着色器。问题是为什么要在同一幅画中使用这么多纹理。据我所知,没有一款 2D 游戏在一个绘制调用中使用超过 2 到 6 个纹理。游戏可能使用 10000 个纹理,但绘制单个精灵或一层 tilemap 只需要 1 或 2 个纹理。
换句话说。一个典型的游戏就可以了
for each layer of tilemap
bind texture atlas for layer (assming it's different than other layers)
draw layer
for each sprite
bind texture for sprite
draw sprite
在上面的例子中,即使你有 10000 个纹理,一次也只有 1 个纹理被使用,所以你没有达到任何限制。
我正在创建一个 HTML5 网络冒险游戏并使用 Tiled 制作地图。
即使使用 Texture Packer,我似乎也超出了纹理单元的最大缓存,因为我收到错误
Texture cache overflow: 16 texture units available
WebGL Stats shows the limit is 16 for ~70% of devices. My browser, as shown here,支持16个纹理单元:
在游戏中,我打开 Chrome 控制台查看 WebGL 规格:
WebGL2RenderingContext.MAX_TEXTURE_IMAGE_UNITS
= 34930WebGL2RenderingContext.MAX_VERTEX_TEXTURE_IMAGE_UNITS
= 35660WebGL2RenderingContext.MAX_COMBINED_TEXTURE_IMAGE_UNITS
= 35661
这有点令人困惑,因为 this article 显示输出应该在 0-10 范围内,而不是 30,000 范围内:
maxTextureUnits = 8
maxVertexShaderTextureUnits = 4
maxFragmentShaderTextureUnits = 8
我的问题:
- 如何确定打包纹理图集中的哪些图像导致了问题?即,我如何检查总纹理?
- 是否可以强制提高缓存限制?
检查这些值的方法是
const maxFragmentShaderTextureUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
const maxVertexShaderTextureUnits = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
const maxTextureUnits = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
此外,这些值与您可以在单个着色器中访问多少纹理有关,而不是您总共可以拥有多少纹理。
它们也与"cache"
无关在您的情况下,您可能希望将纹理组合成一个纹理图集(一个纹理包含所有图块)。
Here's some code that does that。 它加载一个平铺的 json 文件,然后加载所有引用的图像,然后创建一个 2D canvas 并将每个图像的图块复制到 canvas,将地图中的图块重新映射到比赛。完成后,它使用 canvas 作为图块纹理的来源。通常我会离线执行此操作,但很高兴能够点击 "reload" 来查看我在运行时留下的新地图。
在同一个库中 a shader that draws tilemaps including flipped and rotated tiles. In other words, to draw a tiled map it's one draw call per layer and only 2 textures are used. One texture holds the tile images (the texture created above). Another texture holds a layer of a tiled map. The shader reads the tiled map texture and uses that to draw the correct tile from the tile image texture. You can see an explanation of this technique in this article
顺便说一句:带有平铺加载程序的库也有 a shader that can selectively adjust the hue of a sprite. The library was used with a few games, for example this game
- How can I determine which images in my packed texture atlas are causing the issues? I.e., how can I check the total textures?
你管理纹理,而不是 WebGL,所以如果你想知道你使用了多少,添加一些代码来计算它们。
- Is it possible to force a higher cache limit?
不,但正如我上面所说,这与任何缓存无关。
我的猜测是您正在使用某个库,或者您自己的代码正在生成一个着色器,并且您正在向它添加越来越多的纹理,因此着色器生成器生成一个使用过多纹理的着色器。问题是为什么要在同一幅画中使用这么多纹理。据我所知,没有一款 2D 游戏在一个绘制调用中使用超过 2 到 6 个纹理。游戏可能使用 10000 个纹理,但绘制单个精灵或一层 tilemap 只需要 1 或 2 个纹理。
换句话说。一个典型的游戏就可以了
for each layer of tilemap
bind texture atlas for layer (assming it's different than other layers)
draw layer
for each sprite
bind texture for sprite
draw sprite
在上面的例子中,即使你有 10000 个纹理,一次也只有 1 个纹理被使用,所以你没有达到任何限制。