OpenGL如何一次性绑定(成千上万个)纹理?

4

最近我在使用OpenGL时遇到了一些问题。我想要在单次绘制调用中使用大量(超过15k)小型的2D纹理(128x128)。但是我无法高效地完成这个任务。目前我发现的方法及其问题如下:

  1. 据我所知,多纹理的标准解决方案是使用GL_TEXTURE_2D_ARRAY,但通常它的最大尺寸远远不够
  2. 作为替代方案,我可以使用GL_TEXTURE_3D,通常允许更大的深度,但是据我了解,我必须手动生成mipmap(或者干脆不使用?),如果有成千上万层,则可能由于浮点误差在层之间产生颜色渗透
  3. 我可以尝试使用纹理图集的GL_TEXTURE_2D_ARRAY,但那样我还必须考虑如何解决mipmapping或wrapping等问题以及颜色渗透的问题。
  4. 请问是否有更好的方法,如果有,请推荐一个,或者说出我已经概述的三种方法中哪个更好,我是否忽略了什么问题?

1
你也可以生成纹理图集,并将绘制调用拆分成多个具有不同纹理的部分。 - user253751
2
我会选择第三种方法。由于纹理大小是2的幂次方(128),所以不会出现mipmapping的问题(只需确保纹理不会小于1像素)。对于双线性滤波可能会有问题,但我认为对于这种类型的游戏,您想要禁用它!否则,我会使用多个绘制调用和纹理数组。如果用户支持,还可以考虑无绑定纹理。 - tuket
@DFined,这是一个非常好的实验,但你会发现体素引擎不会以这种方式实际工作。所有优秀的游戏引擎都花费了大量的精力来尝试减少被绘制的物品数量,而玩家却无法注意到正在绘制的物品数量减少了。 - user253751
是的,我知道。我计划为远处的物体使用LOD和彩色顶点。但这肯定是可能的,因为“我的世界”(这个可怕的编码实验的起源)一旦加载了几个大型模组,就可以轻松地拥有许多活动纹理,而且我可能错了,但从我所能找到的信息来看,我相信它会将它们保留在VRAM中。我知道“我的世界”曾经使用过纹理图集,但不确定现在是否仍在使用...无论如何,我想我应该尝试一下纹理图集,看看效果如何。 - DFined
谢谢!我实际上不知道 z-buffer 分辨率会成为问题,不过我得设法解决这个问题。但是,我认为普通的 Minecraft 在现代硬件上甚至没有足够的纹理来在数组或者图集中成为问题。不过我可能需要尝试使用一组图集,但我只需要几个。 - DFined
显示剩余3条评论
1个回答

2
如果有人遇到同样的问题,这里有一些后续信息。我选择尝试问题中提到的第三个选项(在启动时使用TEXTURE_2D_ARRAY和每个层都是从不同纹理生成的纹理图集),可以确认,虽然不是理想的方法且有些非传统,但至少它确实有效。此外,虽然将纹理图集数组用作单个图集是不寻常的,但纹理图集本身是非常成熟且易于研究的技术。
目前我只测试了少量纹理,但理论上,使用8192x8192x2048 2D纹理数组的图集,我可以拥有多达800万个128x128的纹理(当然,在实践中由于VRAM限制,实际数量会远远少于这个数字)。
证明概念的图片如下:The proof of concept - a simple 1024x1024 block world with some different textures loaded through an atlas array

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接