Opengl GLSL渲染的纹理多于可用的纹理单元

Opengl GLSL渲染的纹理多于可用的纹理单元,opengl,glsl,Opengl,Glsl,假设您加载了一个具有25个纹理的三维模型,但最多有8个纹理单元。渲染所有纹理最简单/最快速的方法是什么。我想大概是 1) 加载纹理 2) 将纹理绑定到着色器纹理单元 3) 渲染 4) 循环到2),直到渲染所有纹理 我知道绑定是一个代价高昂的过程,因此不确定是否有更好的方法,或者我的理论是否正确……如果所有(或至少部分)纹理的大小相同,则可以使用阵列纹理。您可以通过以下方式创建它们: glTexImage3D(GL_TEXTURE_2D_ARRAY, ...); 如果depth参数用于3D纹理,

假设您加载了一个具有25个纹理的三维模型,但最多有8个纹理单元。渲染所有纹理最简单/最快速的方法是什么。我想大概是

1) 加载纹理 2) 将纹理绑定到着色器纹理单元 3) 渲染 4) 循环到2),直到渲染所有纹理

我知道绑定是一个代价高昂的过程,因此不确定是否有更好的方法,或者我的理论是否正确……

如果所有(或至少部分)纹理的大小相同,则可以使用阵列纹理。您可以通过以下方式创建它们:

glTexImage3D(GL_TEXTURE_2D_ARRAY, ...);
如果
depth
参数用于3D纹理,则传入数组中的纹理数(也称为“层”),如果只想分配内存,则最后一个参数始终为NULL。如果使用OpenGL 4.2或更新版本,还可以使用
glTexStorage3D()
分配纹理内存

然后,您可以使用
glTexSubImage3D(GL\u TEXTURE\u 2D\u ARRAY,…)
在数组中存储每个纹理的数据

在着色器中,对阵列纹理使用类型为
sampler2DArray
的变量,并使用3个纹理坐标对其进行采样,其中第3个“坐标”确定采样的层,对应于阵列中的索引

有时使用的一种完全不同的方法是使用较大的2D纹理,并将每个实际纹理存储为该较大纹理的一部分。然后,可以使用相应的纹理坐标范围来控制对哪些纹理进行采样。假设您在一个纹理中存储了4个相同大小的纹理,其宽度和高度是一个纹理的两倍,那么您将使用范围(0..0.5,0.0..0.5)内的纹理坐标对第一个纹理进行采样,第二个纹理使用范围(0.0..0.5,0.5..1.0),第三个纹理使用范围(0.5..1.0,0.0..0.5..1.0)对第四个纹理进行采样。此方法通常称为“纹理图谱”。

如果所有(或至少部分)纹理的大小相同,则可以使用阵列纹理。您可以通过以下方式创建它们:

glTexImage3D(GL_TEXTURE_2D_ARRAY, ...);
如果
depth
参数用于3D纹理,则传入数组中的纹理数(也称为“层”),如果只想分配内存,则最后一个参数始终为NULL。如果使用OpenGL 4.2或更新版本,还可以使用
glTexStorage3D()
分配纹理内存

然后,您可以使用
glTexSubImage3D(GL\u TEXTURE\u 2D\u ARRAY,…)
在数组中存储每个纹理的数据

在着色器中,对阵列纹理使用类型为
sampler2DArray
的变量,并使用3个纹理坐标对其进行采样,其中第3个“坐标”确定采样的层,对应于阵列中的索引


有时使用的一种完全不同的方法是使用较大的2D纹理,并将每个实际纹理存储为该较大纹理的一部分。然后,可以使用相应的纹理坐标范围来控制对哪些纹理进行采样。假设您在一个纹理中存储了4个相同大小的纹理,其宽度和高度是一个纹理的两倍,那么您将使用范围(0..0.5,0.0..0.5)内的纹理坐标对第一个纹理进行采样,第二个纹理使用范围(0.0..0.5,0.5..1.0),第三个纹理使用范围(0.5..1.0,0.0..0.5..1.0)对第四个纹理进行采样。这种方法通常被称为“纹理图谱”。

这个答案是作为Reto Koradi答案的旁注,我认为他的答案更相关。然而,我想补充一点,对于真正现代的GPU,有 它允许你使用尽可能多的纹理,你可以进入内存,完全绕过任何GL“纹理单位”


目前,这个扩展不是核心OpenGL的一部分,它只在NVidia GPU上支持,因为“开普勒”架构和AMD GPU上支持“图形核心下一代”架构。这个答案是作为Reto Koradi答案的旁注,我认为他的答案更相关。然而,我想补充一点,对于真正现代的GPU,有 它允许你使用尽可能多的纹理,你可以进入内存,完全绕过任何GL“纹理单位”


目前,此扩展不是核心OpenGL的一部分,并且自“开普勒”架构以来,仅在NVidia GPU上支持,自“图形核心下一代”架构以来,仅在AMD GPU上支持。

既然您正在讨论glsl,我认为值得指出的是,纹理图像单元的数量实际上与一个过程中可以应用的离散纹理的数量是分开的

例如,德国劳埃德船级社3.3保证48个TIU(管道中每个阶段16个)。。。这48个单元允许您在足够的位置绑定纹理,以便可以在顶点、几何体和片段着色器中使用一组16种不同的纹理。但是,这并不意味着可以在片段着色器中采样48种不同的纹理


在着色器调用中可以采样的纹理数量有一个阶段限制(最少16个,每个阶段的限制可能不同)。还有一个适用于每个阶段的总限额(GL 3.3中至少有48个)。因此,尽管您可以在任何给定的时间绑定48种不同的纹理,但您仍然需要将绘图拆分为3次才能实际应用所有48种纹理。

因为您正在讨论glsl,我认为值得指出的是,纹理图像单元的数量实际上与一个过程中可以应用的离散纹理的数量是分开的

例如,德国劳埃德船级社3.3保证48个TIU(管道中每个阶段16个)。。。这48个单元允许您在足够的位置绑定纹理,以便可以在顶点、几何体和片段着色器中使用一组16种不同的纹理。但是,这并不意味着可以在片段着色器中采样48种不同的纹理

每个阶段都有一个限制