[英]Correspondance between texture units and sampler uniforms in opengl
glActiveTexture
使用的采样器制服和纹理单元之间的对应关系显然无法用 opengl 查询,而且我找不到关于如何找到哪个纹理单元映射到哪个采样器制服的好的文档。 这是我能够找到的:
gl_TEXTURE0
例如,如果顶点着色器定义:
uniform sampler2D color;
片段着色器定义:
uniform sampler2D tex;
uniform sampler2D norm;
然后color
被映射到gl_TEXTURE0
, tex
被映射到gl_TEXTURE1
, norm
被映射到gl_TEXTURE2
。 但是如果顶点着色器定义为:
uniform sampler2D norm;
然后不清楚如何映射不同的纹理。 由于具有布局限定符或单独的着色器阶段的可能性,这也变得更加复杂。
我似乎无法在任何地方找到有关此的文档。 我所知道的一切要么来自我自己的实验,要么来自 Stackoverflow 或 OpenGL 论坛上的答案。 有没有人知道在所有可能的情况下如何工作的一套全面规则,或者查询采样器对应的纹理单元的方法?
这是我能够找到的:
- 如果程序中只有采样器uniform,则映射到
gl_TEXTURE0
- 如果在单个程序阶段中有多个采样器制服,则它们将按照它们在着色器中声明的顺序进行映射。
- 如果顶点着色器和片段着色器具有不相交的采样器统一集,则顶点着色器中的采样器首先出现,然后是片段着色器中的采样器。
- 这种行为似乎是由规范定义的。
这一切都不是真的。 好吧,第一个是真的,但只是偶然。
所有未在着色器中初始化的统一值都被初始化为值 0。规范对此非常清楚:
任何没有绑定限定符声明的统一采样器或图像变量最初都绑定到零单元。
采样器统一的值是它代表的纹理单元的整数索引。 所以 0 值对应于GL_TEXTURE0
。 所有未初始化的采样器制服的值都应为 0。
如果您描述的行为正在发生,则该实现违反了 OpenGL 规范。
除非您使用layout(binding = )
语法来分配统一的纹理单元,否则您必须在 OpenGL 代码中手动为每个采样器统一分配一个纹理单元的值。 这是通过设置它的统一值来完成的,就像任何其他整数统一:你调用glUniform1i
与对应于该统一的位置。 因此,如果您想将它与纹理图像单元索引 4 相关联,您可以调用glUniform1i(..., 4)
,其中...
是该制服的统一位置。
您必须将纹理单元的索引设置为采样器统一(类似于设置int
类型的统一变量的值)。 例如GL_TEXTURE1
值为 1 。
请参阅OpenGL 4.6 API 兼容性配置文件规范; 7.10 取样器; 第 154 页:
采样器是 OpenGL 着色语言中使用的特殊统一体,用于标识用于每个纹理查找的纹理对象。 采样器的值表示正在访问的纹理图像单元。 将采样器的值设置为
i
选择纹理图像单元编号i
。
例如
layout (location = 11) uniform sampler2D color;
layout (location = 12) uniform sampler2D tex;
layout (location = 13) uniform sampler2D norm;
glUniform1i(11, 0); // 0: GL_TEXTURE0
glUniform1i(12, 1); // 1: GL_TEXTURE1
glUniform1i(13, 2); // 2: GL_TEXTURE2
从 GLSL 4.2 版开始,这可以通过指定绑定点在片段着色器中完成 - 请参阅OpenGL Shading Language 4.20 Specification - 4.4.4 Opaque-Uniform Layout Qualifiers; 第 60 页:
#version 420
layout (binding = 0) uniform sampler2D color;
layout (binding = 1) uniform sampler2D tex;
layout (binding = 2) uniform sampler2D norm;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.