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

Nic*_*las 8 opengl textures opengl-4

OpenGL具有数组纹理,由特定采样器类型的着色器表示:

sampler2DArray array_texture;
Run Code Online (Sandbox Code Playgroud)

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

sampler2D array_of_textures[10];
Run Code Online (Sandbox Code Playgroud)

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

Nic*_*las 8

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

int*                 pi;
std::array<int, 5>*  pai;
std::array<int*, 5>  api;
Run Code Online (Sandbox Code Playgroud)

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

pai也是一个指针.但它没有指出一个int; 它指向一个arrayint秒.这" arrayints"为单个对象,具有存储的单个连续分配.

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

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

  • pi就像sampler2D.
  • pai就像sampler2DArray:一个指针/采样器,它引用int所有驻留在单个对象中的多个/ 2D纹理.
  • api就像一个sampler2D[]:表示多个指针/采样器的单个名称,每个指针/采样器都是独立绑定的,引用不相关的对象,除非它们都必须是int/ sampler2Ds.

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

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

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

但不是任意的运行时索引.您只能使用动态统一表达式的索引.也就是说,对于绘图命令中的所有调用,执行该指令的每个调用必须生成相同的索引.

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

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