javascript - WebGL HTML5 游戏的纹理缓存溢出

标签 javascript html webgl textures

我正在创建一个 HTML5 网络冒险游戏并使用 Tiled 制作图 block map 。 .

即使有 Texture Packer ,我似乎超出了纹理单元的最大缓存,因为我收到了错误

Texture cache overflow: 16 texture units available

WebGL Stats显示约 70% 的设备的限制为 16。我的浏览器,如图here ,支持16个纹理单元:

enter image description here

在游戏中,我打开 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);

此外,这些值与您可以在单个着色器中访问的纹理数量有关,而不是与您总共可以拥有的纹理数量有关。

它们也与“缓存”无关

在您的情况下,您可能希望将纹理组合成单个纹理图集(一个包含所有图 block 的纹理)。

Here's some code that does that 。 它加载一个平铺的 json 文件,然后加载所有引用的图像,然后创建一个 2D Canvas 并将每个图像中的图 block 复制到 Canvas 中,重新映射 map 中的图 block 以匹配。完成后,它使用 Canvas 作为图 block 纹理的来源。通常我会离线执行此操作,但很高兴能够点击“重新加载”来查看我在运行时留下的新 map 。

在同一个库中是 a shader that draws tilemaps包括翻转和旋转的瓷砖。换句话说,要绘制平铺 map ,每层需要一次绘制调用,并且仅使用 2 个纹理。一个纹理保存图 block 图像(上面创建的纹理)。另一个纹理包含一层平铺 map 。着色器读取平铺贴图纹理,并使用它从平铺图像纹理中绘制正确的平铺。你可以看到这个技术的解释in this article

顺便说一句:带有平铺加载程序的库还有 a shader that can selectively adjust the hue of a sprite 。该库用于一些游戏,例如 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 个纹理,但要绘制单个 Sprite 或一层图 block map ,只需要 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 个纹理,因此您不会遇到任何限制。

关于javascript - WebGL HTML5 游戏的纹理缓存溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57683611/

相关文章:

php - 什么是最好的 WYSIWYG contenteditable 插件,用于编辑 HTML,同时保留动态 PHP/ASP/等。内容?

javascript - 显示/隐藏搜索 Div Angular UI

jquery - Div 类仅隐藏在 jQuery Tab 中

javascript - 有没有办法在 three.js 中的纹理之间进行自定义转换

javascript - Angular 处理多个依赖订阅

javascript - 使每条 Canvas 线都可拖放

google-chrome - 为什么 getContext() 在 Ubuntu 上的 Chrome 上返回 null

javascript - WebGL iOS 渲染到浮点纹理

javascript - 将 Django DateTime 对象序列化为 json 然后实例化 JS Date 对象并返回的最佳方法是什么?

javascript - `onselectionchange` 的 HTML5 事件