阵列纹理与采样器阵列相关吗?
Are array textures related to sampler arrays?
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
数组的指针)。
pai
也是一个指针。但它并不指向 int
;它指向 int
中的 array
。 int
s 中的“array
”是单个对象,具有单个连续的存储分配。
api
不是指针;它是一个 数组 。具体来说,它是一个指向 int
的指针数组。每个单独的指针都可以指向单独的 int
个对象。每个单独的指针都独立于其他指针,它们指向的对象完全不相关,除了它们都必须是 int
s.
这与 OpenGL 和纹理有什么关系?
pi
就像 sampler2D
.
pai
类似于 sampler2DArray
:单个 pointer/sampler 引用多个 int
/2D 纹理,这些纹理都驻留在单个对象中。
api
就像一个 sampler2D[]
:一个名称代表多个 pointers/samplers,每个名称都是独立绑定的,引用不相关的对象,除了它们都必须是 int
/sampler2D
s.
数组纹理与 non-array 纹理不同。数组纹理有一个特殊的纹理目标。在 GLSL 中访问数组纹理需要明确使用与目标匹配的不同采样器类型。采用数组纹理的纹理访问函数采用额外的纹理坐标组件,提供要访问的数组层。当您将纹理分配给数组纹理采样器时,您分配的是单个纹理对象,无论它创建时使用的数组层数是多少。
相比之下,采样器数组只是 compile-time 大小的多个独立采样器的集合,这些采样器以一个名称分组。纹理被独立分配到数组中的位置,可以使用适当类型的任何纹理。数组的每个元素占用一个额外的绑定点。
除了资源消耗之外,最大的区别在于:您可以使用运行时索引从数组中选择一个采样器(在 OpenGL 4.x 中;在 4.x 之前,您必须使用 compile-time常量。所以采样器数组基本上没用)。
但不是任意运行时索引。您只能使用 dynamically uniform expression 的索引。也就是说,对于绘图命令中的所有调用,执行该指令的每个调用必须产生相同的索引。
数组纹理没有这样的索引限制;您在纹理获取命令中提供的数组索引可以是任何运行时值(当然在数组内)。
但是阵列纹理确实有其他限制。数组纹理中的每个 "texture" 具有相同的大小;所以如果你创建一个 512x512x20 的二维数组纹理,每个 sub-texture 是 512x512。对于采样器数组,数组中每个纹理的大小可以变化。当然,每个采样器数组索引占用一个绑定点这一事实也很重要;您只有其中的 16 个 per-stage(尽管可能更多;16 个是最低要求)。
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
数组的指针)。
pai
也是一个指针。但它并不指向 int
;它指向 int
中的 array
。 int
s 中的“array
”是单个对象,具有单个连续的存储分配。
api
不是指针;它是一个 数组 。具体来说,它是一个指向 int
的指针数组。每个单独的指针都可以指向单独的 int
个对象。每个单独的指针都独立于其他指针,它们指向的对象完全不相关,除了它们都必须是 int
s.
这与 OpenGL 和纹理有什么关系?
pi
就像sampler2D
.pai
类似于sampler2DArray
:单个 pointer/sampler 引用多个int
/2D 纹理,这些纹理都驻留在单个对象中。api
就像一个sampler2D[]
:一个名称代表多个 pointers/samplers,每个名称都是独立绑定的,引用不相关的对象,除了它们都必须是int
/sampler2D
s.
数组纹理与 non-array 纹理不同。数组纹理有一个特殊的纹理目标。在 GLSL 中访问数组纹理需要明确使用与目标匹配的不同采样器类型。采用数组纹理的纹理访问函数采用额外的纹理坐标组件,提供要访问的数组层。当您将纹理分配给数组纹理采样器时,您分配的是单个纹理对象,无论它创建时使用的数组层数是多少。
相比之下,采样器数组只是 compile-time 大小的多个独立采样器的集合,这些采样器以一个名称分组。纹理被独立分配到数组中的位置,可以使用适当类型的任何纹理。数组的每个元素占用一个额外的绑定点。
除了资源消耗之外,最大的区别在于:您可以使用运行时索引从数组中选择一个采样器(在 OpenGL 4.x 中;在 4.x 之前,您必须使用 compile-time常量。所以采样器数组基本上没用)。
但不是任意运行时索引。您只能使用 dynamically uniform expression 的索引。也就是说,对于绘图命令中的所有调用,执行该指令的每个调用必须产生相同的索引。
数组纹理没有这样的索引限制;您在纹理获取命令中提供的数组索引可以是任何运行时值(当然在数组内)。
但是阵列纹理确实有其他限制。数组纹理中的每个 "texture" 具有相同的大小;所以如果你创建一个 512x512x20 的二维数组纹理,每个 sub-texture 是 512x512。对于采样器数组,数组中每个纹理的大小可以变化。当然,每个采样器数组索引占用一个绑定点这一事实也很重要;您只有其中的 16 个 per-stage(尽管可能更多;16 个是最低要求)。