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)
这两个功能是否相互关联?他们有什么不同?
让我们通过类比来理解这种区别.GLSL中的采样器就像C++中的指针一样; 它们引用了给定类型的其他对象.所以请考虑以下C++代码:
int* pi;
std::array<int, 5>* pai;
std::array<int*, 5> api;
Run Code Online (Sandbox Code Playgroud)
pi
是指向单个类型对象的指针int
(让我们忽略这样一个事实,即技术上它可能是指向int
s 数组的指针).
pai
也是一个指针.但它没有指出一个int
; 它指向一个array
的int
秒.这" array
的int
s"为单个对象,具有存储的单个连续分配.
api
不是指针; 这是一个数组.具体来说,它是一个指向int
s 的指针数组.每个指针都可以指向单个int
对象.每个单独的指针都与其余指针无关,它们指向的对象完全不相关,除非它们都必须是int
s.
这与OpenGL和纹理有什么关系?
pi
就像sampler2D
.pai
就像sampler2DArray
:一个指针/采样器,它引用int
所有驻留在单个对象中的多个/ 2D纹理.api
就像一个sampler2D[]
:表示多个指针/采样器的单个名称,每个指针/采样器都是独立绑定的,引用不相关的对象,除非它们都必须是int
/ sampler2D
s.数组纹理是与非数组纹理不同的构造.数组纹理具有特殊的纹理目标.在GLSL中访问数组纹理需要显式使用与目标匹配的不同采样器类型.采用数组纹理的纹理访问函数采用额外的纹理坐标组件,从而提供要访问的数组层.将纹理指定给数组纹理采样器时,您将分配单个纹理对象,其中创建的数组层数不限.
相比之下,采样器数组只是一个编译时大小的多个独立采样器集合,这些采样器分组在一个名称下.纹理被独立地分配给数组中的位置,可以使用任何适当类型的纹理.数组的每个元素都占用一个额外的绑定点.
除了资源消耗之外最大的区别是:你可以使用运行时索引从数组中选择一个采样器(在OpenGL 4.x中;在4.x之前,你必须使用编译时常量.所以采样器数组基本上是无用).
但不是任意的运行时索引.您只能使用动态统一表达式的索引.也就是说,对于绘图命令中的所有调用,执行该指令的每个调用必须生成相同的索引.
数组纹理没有这样的索引限制; 您在纹理提取命令中提供的数组索引可以是任何运行时值(当然,在数组中).
但阵列纹理确实有其他限制.数组纹理中的每个"纹理"都具有相同的大小; 因此,如果您创建512x512x20 2D阵列纹理,则每个子纹理为512x512.对于采样器阵列,阵列中每个纹理的大小可以变化.当然,每个采样器数组索引占据绑定点的事实也很重要; 每个阶段只有16个(尽管可能更多; 16个是最低要求).