Inf*_*her 3 opengl shader glsl
glActiveTexture显然不能用opengl查询采样器制服和纹理单元之间的对应关系,我找不到关于如何找到哪个纹理单元映射到哪个采样器制服的好文档。这是我能够找到的:
gl_TEXTURE0例如,如果顶点着色器定义:
uniform sampler2D color;
Run Code Online (Sandbox Code Playgroud)
片段着色器定义:
uniform sampler2D tex;
uniform sampler2D norm;
Run Code Online (Sandbox Code Playgroud)
然后color被映射到gl_TEXTURE0,tex被映射到gl_TEXTURE1,然后norm被映射到gl_TEXTURE2。但是如果顶点着色器定义为:
uniform sampler2D norm;
Run Code Online (Sandbox Code Playgroud)
然后不清楚如何映射不同的纹理。由于具有布局限定符或单独的着色器阶段的可能性,这也变得更加复杂。
我似乎无法在任何地方找到有关此的文档。我所知道的一切要么来自我自己的实验,要么来自 Stackoverflow 或 OpenGL 论坛上的答案。有没有人知道在所有可能的情况下如何工作的一套全面的规则,或者查询采样器对应的纹理单元的方法?
这是我能够找到的:
- 如果程序中只有采样器统一,那么它被映射到
gl_TEXTURE0- 如果在单个程序阶段中有多个采样器制服,则它们将按照它们在着色器中声明的顺序进行映射。
- 如果顶点着色器和片段着色器具有不相交的采样器统一集,则顶点着色器中的采样器首先出现,然后是片段着色器中的采样器。
- 这种行为似乎是由规范定义的。
这一切都不是真的。好吧,第一个是真的,但只是偶然。
所有未在着色器中初始化的统一值都被初始化为值 0。规范对此非常清楚:
任何没有绑定限定符声明的统一采样器或图像变量最初都绑定到零单元。
采样器统一的值是它代表的纹理单元的整数索引。因此,值 0 对应于GL_TEXTURE0。所有未初始化的采样器制服的值都应为 0。
如果您描述的行为正在发生,则该实现违反了 OpenGL 规范。
除非您使用layout(binding = )语法来分配统一的纹理单元,否则您必须在 OpenGL 代码中手动为每个采样器统一分配一个纹理单元的值。这是通过设置它的统一值来完成的,就像任何其他整数统一:你调用glUniform1i与该统一对应的位置。因此,如果您想将它与纹理图像单元索引 4 相关联,您可以调用glUniform1i(..., 4),其中...是该制服的统一位置。
您必须将纹理单元的索引设置为采样器统一(类似于设置类型的统一变量的值int)。例如 的值为 1 GL_TEXTURE1。
请参阅OpenGL 4.6 API 兼容性配置文件规范;7.10 采样器;第154页:
\n\n\n\n\n采样器是 OpenGL 着色语言中使用的特殊制服,用于识别每个纹理查找所使用的纹理对象。采样器的值指示正在访问的纹理图像单元。设置 Sampler\xe2\x80\x99s 值来
\ni选择纹理图像单元号i。
例如
\n\nlayout (location = 11) uniform sampler2D color;\nlayout (location = 12) uniform sampler2D tex;\nlayout (location = 13) uniform sampler2D norm;\nRun Code Online (Sandbox Code Playgroud)\n\nglUniform1i(11, 0); // 0: GL_TEXTURE0\nglUniform1i(12, 1); // 1: GL_TEXTURE1\nglUniform1i(13, 2); // 2: GL_TEXTURE2\nRun Code Online (Sandbox Code Playgroud)\n\n从 GLSL 版本 4.2 开始,这可以通过指定绑定点在片段着色器中完成 - 请参阅OpenGL 着色语言 4.20 规范 - 4.4.4 不透明统一布局限定符;第60页:
\n\n#version 420\n\nlayout (binding = 0) uniform sampler2D color;\nlayout (binding = 1) uniform sampler2D tex;\nlayout (binding = 2) uniform sampler2D norm;\nRun Code Online (Sandbox Code Playgroud)\n