0

我正在尝试使用 WebGL 创建游戏。

我目前有三个纹理,一个是字体的字母,一个是角色的精灵表,一个是世界的瓦片图。所以我有一些大的纹理,我需要多次绘制其中的一小部分。

做这个的最好方式是什么?

我目前的方法是为每个字母、地图上的正方形、角色姿势等使用 VAO……所以我会有 150 多个 VAO。我认为 VAO 很好,因为它们既简单又快速,但是thisthis和其他让这看起来不是最好的选择。

例如,我知道的另一种方法是只有三个 VAO 并更改 WebGL 在缓冲区中开始读取的位置以获取正确字母的位置。因此,我将拥有三个带有大型阵列的 VAO,而不是数百个带有小阵列的 VAO。如果这是正确的方法,我每次绘制东西时是否必须在 gl.enablevertexAttribArray() 之后调用 gl.vertexAttribPointer() ,还是只修改 gl.drawArrays() 中的 count 参数?

gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) 是 16 或 32,因此切碎纹理似乎也不是一个好方法。

最好的概念方法是什么?

4

1 回答 1

1

有多少 VAO 取决于您。有很多权衡。就文本而言,最常见的文本方式是将字形放入纹理图集中,并为要绘制的所有字母生成一个包含顶点的缓冲区。

换句话说。

each frame
   for each string
      for each letter in string
         add vertices for letter to buffer

drawArray/drawElements(gl.TRIANGLES, ... totalOfAllLettersInAllStrings * 6);

因此,所有字母(如 UI)可能只有一个绘制调用。每个字母没有一个。那将是缓慢的方式。

这是一篇关于它的文章

您对 MAX_TEXTURE_IMAGE_UNITS 的评论听起来也可能存在误解?纹理单元只是着色器在单个绘制调用中可以引用的最大纹理数量。它们不是纹理周期的最大数量。您可以拥有 1000 种纹理。每次绘制调用时,您只能为它们引用一个特定的数字。

就绘制文本而言,对于简单的情况,通常每种字体样式只需要一个纹理。虽然如果你想支持所有的 unicode 而不是只说 ASCII,它会很快变得复杂。

于 2020-10-19T17:16:07.200 回答