opengl - 阵列纹理是否与采样器阵列相关?

标签 opengl textures opengl-4

OpenGL 有 array textures ,在着色器中由特定的采样器类型表示:

sampler2DArray array_texture;

但是 GLSL 也允许将采样器聚合到数组中:
sampler2D array_of_textures[10];

这两个功能是否相互关联?它们有何不同?

最佳答案

让我们通过类比来理解区别。 GLSL 中的采样器就像 C++ 中的指针;它们引用给定类型的其他对象。因此,请考虑以下 C++ 代码:

int*                 pi;
std::array<int, 5>*  pai;
std::array<int*, 5>  api;
pi是指向 int 类型的单个对象的指针(让我们忽略一个事实,从技术上讲,它可能是指向 int s 数组的指针)。
pai也是一个指针。但它并不指向 int ;它指向 arrayint s。 “array of int s”是单个对象,具有单个连续的存储分配。
api不是指针;它是一个数组。具体来说,它是一个指向 int 的指针数组。 s。每个单独的指针都可以指向单独的 int对象。每个单独的指针都独立于其他指针,它们指向的对象完全不相关,除了它们都必须是 int 之外。 s。

这与 OpenGL 和纹理有什么关系?
  • pi就像 sampler2D .
  • pai就像 sampler2DArray : 引用多个 int 的单个指针/采样器/2D 纹理都位于单个对象中。
  • api就像 sampler2D[] :代表多个指针/采样器的单个名称,每个指针/采样器都是独立绑定(bind)的,引用不相关的对象,除非它们都必须是 int/sampler2D s。

  • 数组纹理是与非数组纹理不同的构造。数组纹理有一个特殊的纹理目标。在 GLSL 中访问数组纹理需要显式使用与目标匹配的不同采样器类型。采用数组纹理的纹理访问函数采用额外的纹理坐标分量,提供要访问的数组层。当您将纹理分配给阵列纹理采样器时,您分配的是单个纹理对象,无论创建它的阵列层数如何。

    相比之下,采样器数组只是按一个名称分组的多个独立采样器的编译时大小的集合。纹理被独立地分配到数组中的位置,任何适当类型的纹理都可以使用。数组的每个元素占用一个额外的绑定(bind)点。

    除了资源消耗之外,最大的区别在于:您可以使用运行时索引从数组中选择一个采样器(在 OpenGL 4.x 中;在 4.x 之前的版本中,您必须使用编译时常量。所以采样器数组基本上是无用)。

    但不是任意的运行时索引。您只能使用 dynamically uniform expression 的索引.也就是说,对于绘图命令中的所有调用,执行该指令的每个调用都必须产生相同的索引。

    数组纹理没有这样的索引限制;您在纹理获取命令中为它们提供的数组索引可以是任何运行时值(当然,在数组内)。

    但是数组纹理确实有其他限制。数组纹理中的每个“纹理”都具有相同的大小;所以如果你创建一个 512x512x20 的二维数组纹理,每个子纹理都是 512x512。对于采样器数组,数组中每个纹理的大小可以变化。当然,每个采样器数组索引占用一个绑定(bind)点这一事实也很重要;每个阶段您只有 16 个(尽管可能更多;16 是最低要求)。

    关于opengl - 阵列纹理是否与采样器阵列相关?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48858768/

    相关文章:

    c++ - 使用 FBO 的 OpenGL 着色管道效率

    c++ - glStencil 能做什么?

    android - 为 Sprite 表使用纹理时防止间隙/边界

    c# - OpenGL 尝试绘制多个 2d 纹理,只出现第一个

    XNA .Fbx 纹理

    c++ - 如何使用无绑定(bind)指定 UBO 绑定(bind)?

    c++ - 离屏渲染 opengl 4.5 多采样 FBO

    opengl - 在 OpenGL 中使用不同的缓冲区绘制多个对象

    c++ - 如何开始使用 GPU 体素化器?

    opengl - OpenGL 3.1 中已弃用 glLineStipple