【问题标题】:What are the limits of texture array size?纹理数组大小的限制是什么?
【发布时间】:2018-07-05 11:08:02
【问题描述】:

我有点了解纹理数组是关于什么的,但在互联网上我找不到关于它们实际上是什么的信息。它们是像一个大的纹理图集(单个连续的内存块被分成相等尺寸的部分),还是像纹理单元(完全独立的纹理,你可以一次绑定)?这个问题的结果是,单个纹理数组的大小限制是多少,以及如何有效地使用它们?例如,如果我的 GPU 处理 4096x4096 纹理和 64 个单元,我可以创建一个包含 64 个 4096x4096 纹理的纹理数组吗?还是每个阵列的实际限制为 4096*4096 像素?或者也许是别的什么?如何查询限额?

【问题讨论】:

    标签: opengl textures


    【解决方案1】:

    它们是图像数组(这个概念通常被称为分层图像,因为有多种类型的纹理实际上存储了多个图像)。数组纹理的特殊之处在于它的每一层都具有相同的维度。此外,虽然内存的分配方式与 3D 纹理相同,但数组纹理无法跨图像层进行过滤,并且 2D 数组纹理的 mipmap 链仍然是 2D。

    最早引入的数组纹理形式是立方体贴图,它有 6 个 2D 层...但它也有一组特殊的查找函数,因此它与通用的 2D 数组纹理相去甚远。

    尽管如此,您正在讨论的限制是阵列纹理中的每个图像尺寸。也就是说,如果您的最大纹理大小为 4096,这意味着 2D 纹理被限制为 4096x4096per-image 以获得最高细节 mipmap 级别.

    阵列纹理中的图层根本不像纹理图像单元。它们独立的图像,但它们都属于单个纹理对象,可以绑定到单个纹理图像单元。

    你的数组纹理中的最大层数可以这样查询:

    GLint max_layers;
    glGetIntegerv (GL_MAX_ARRAY_TEXTURE_LAYERS, &max_layers);
    

    关于有效使用数组纹理的话题,您可以考虑一个称为稀疏数组纹理的新功能(通过GL_ARB_sparse_texture)。

    假设您想4096 x 4096 x 64 阵列纹理保留足够的存储空间,但最初实际上只使用了其中的 4 或 5 个层。通常这会非常浪费,但是对于稀疏的纹理,只有正在使用的 4 或 5 层必须驻留(已提交)。其余层的处理就像操作系统中的按需分页虚拟内存一样。直到第一次使用才真正分配后备存储。

    【讨论】:

    • 关于稀疏纹理,我对它与旧硬件的兼容性没有足够的信心来使用它——你知道,我正在制作一个 2D 游戏,我宁愿不使用任何不是的东西t 99% 保证可以在任何硬件上运行。如果我最初制作了一层深的纹理数组,如果我需要另一个,使用 glTexImage3D 调整它的大小,它不会工作吗?我正在使用 OGL 3.2。
    • 是的,如果您打算支持旧硬件,我不会使用它。它通常是 DX11.2 类硬件功能,较旧的 GPU 可以支持它,但不符合 GL4.4 / DX11.2 的任何东西都需要来支持它。您可以肯定地调整数组纹理的大小,但稀疏数组纹理的方便之处在于您不限于从 0 开始的索引(例如,对于讨论的 64 层数组纹理,您可能有在 34 和 46 处仅分配了 2 个图像 - 通常它们需要在 0 和 1),因此它可以简化诸如 atlas 打包之类的事情。
    • 还有一个问题。如果我在现有纹理数组上使用 glTexImage3D 与空数据(如,只是为了调整大小),并使用相同的宽度和高度,但不同的深度,是否保证较低层的数据保持不变?
    • 不幸的是,没有。 glTexImage* (...) 函数实际上等效于 C 中 malloc (...)free (...) 的组合。它们将在未处理的命令不再使用原始纹理内存时释放它,并将分配 new 存储空间.要在保留数据的同时调整纹理大小,您必须创建一个新纹理并使用glCopyTexSubImage3D (...) 传输旧图像数据。它会比这更复杂,因为glCopyTexSubImage3D (...) 使用读取缓冲区,所以你的原始纹理必须附加到 FBO 才能工作:-\
    猜你喜欢
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2018-08-08
    • 1970-01-01
    • 2015-05-16
    • 2023-03-08
    相关资源
    最近更新 更多