数组纹理是否与采样器数组相关?

时间:2018-02-19 02:21:37

标签: opengl textures opengl-4

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

sampler2DArray array_texture;

但GLSL还允许将采样器聚合到数组中:

sampler2D array_of_textures[10];

这两个功能是否相互关联?他们有什么不同?

1 个答案:

答案 0 :(得分:8)

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

int*                 pi;
std::array<int, 5>*  pai;
std::array<int*, 5>  api;

pi是指向int类型的单个对象的指针(让我们忽略这样一个事实,即技术上它可能是指向int s数组的指针。

pai也是一个指针。但它没有指向int;它指向array的{​​{1}}。 “int的{​​{1}}”只是一个对象,只有一个连续的存储分配。

array不是指针;它是数组。具体来说,它是指向int的指针数组。每个指针都可以指向单个api个对象。每个单独的指针都与其余指针无关,它们指向的对象完全不相关,除非它们都必须是int s。

这与OpenGL和纹理有什么关系?

  • intint类似。
  • pisampler2D类似:单个指针/采样器,它引用多个pai / 2D纹理,这些纹理都位于单个对象中。
  • sampler2DArray就像一个int:一个代表多个指针/采样器的名称,每个指针/采样器都是独立绑定的,引用不相关的对象,除非它们都必须是{{ 1}} / api秒。

数组纹理是与非数组纹理不同的构造。数组纹理具有特殊的纹理目标。在GLSL中访问数组纹理需要显式使用与目标匹配的不同采样器类型。采用数组纹理的纹理访问函数采用额外的纹理坐标组件,从而提供要访问的数组层。将纹理指定给数组纹理采样器时,您将分配单个纹理对象,其中包含创建的数组层数。

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

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

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

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

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