5

我正在编写一个批处理系统来跟踪当前绑定的纹理,以避免不必要的glBindTexture()调用。我不确定是否需要跟踪特定批次已经使用了哪些纹理,以便如果纹理被使用两次,它将绑定到需要它的第二个采样器的不同 TIU。

OpenGL 应用程序可以为同一着色器阶段内的多个采样器使用相同的纹理图像单元吗?不同着色器阶段的采样器呢?例如:

片段着色器:

...
uniform sampler2D samp1;
uniform sampler2D samp2;

void main() { ... }

主程序:

...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_id);
glUniform1i(samp1_location, 0);
glUniform1i(samp2_location, 0);
...

我看不出这不应该起作用的任何原因,但是如果着色器程序还包括这样的顶点着色器呢:

顶点着色器:

...
uniform sampler2D samp1;

void main() { ... }

在这种情况下,OpenGL 应该将 的两个实例samp1视为引用相同的位置。因此,在顶点着色器和片段着色器中使用了相同的纹理单元。我已经读过在两个不同的着色器阶段使用相同的纹理是双重的,GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS但这似乎与此相矛盾。

在对我的硬件(HD 6870)进行的快速测试中,以下所有场景都按预期工作:

  • 1 TIU 用于同一着色器阶段中的 2 个采样器制服
  • 1 个 TIU 用于 1 个采样器制服,用于 2 个着色器阶段
  • 1 TIU 用于 2 件采样器制服,每件都发生在不同的阶段。

但是,我不知道这是否是我应该在所有硬件/驱动程序上预期的行为,或者是否存在性能影响。

4

1 回答 1

4

希望这会消除您的一些困惑,我使用的是旧版本的规范。为简单起见,较新的版本有两个额外的阶段(镶嵌控制/评估),因此讨论有点复杂。

OpenGL 3.3(核心配置文件) - 2.11。顶点着色器 - 第 80 页

纹理访问

着色器能够查找纹理贴图。顶点、几何或片段着色器可用的纹理图像单元的最大数量分别是与实现相关的常量GL_MAX_VERTEX_TEXTURE_IMAGE_UNITSGL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS和的值GL_MAX_TEXTURE_IMAGE_UNITS。顶点着色器、几何着色器和片段着色器组合使用的值不能超过GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS纹理图像单元的值。如果多个顶点着色器、几何着色器和片段处理阶段访问同一个纹理图像单元,则每个此类访问都单独计入GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS限制。

该限制是根据每个阶段中使用的唯一采样器的数量施加的。就使用确定而言,具有不同名称但引用相同纹理单元的两个采样器制服实际上是相同的。用法是指做类似的事情texture (sampler, coords),如果这不是很明显的话。仅仅声明一个采样器并为其分配一个值不会让您更接近实现定义的限制,您实际上必须在运行时使用采样器,并且如果它与同一阶段中另一个使用的采样器具有相同的值它不算数。

至于多次使用同一个纹理对象,不,这不是GL_MAX_..._IMAGE_UNITS限制的全部内容。您可以将相同的纹理绑定到所有 48 个纹理单元(GL3.3 中的最低实现要求 - 这实际上要求每个阶段至少有 16 个纹理),如果您愿意,此限制是指您使用的不同采样器的数量(再次,请参阅以上)在着色器阶段。如果您需要使用最近邻过滤一次,而另一次使用线性或不同的包裹状态,您实际上可能希望将相同的纹理绑定到多个纹理单元。

如果您想知道所有驱动程序/硬件的预期行为,请始终查阅正式的 OpenGL 规范。我为您挑选了相关信息,但是如果您将来学习如何通过这些信息搜索重要的详细信息,将会对您有所帮助。自 OpenGL 1.0 以来的所有规范均可从以下网址免费获得:http ://www.opengl.org/registry/ 。

于 2013-10-20T02:51:04.987 回答