简体   繁体   English

opengl中纹理单元和采样器制服的对应关系

[英]Correspondance between texture units and sampler uniforms in opengl

The correspondence between sampler uniforms and texture units used by glActiveTexture apparently can't be queried with opengl, and I can't find good documentation on how to find which texture unit is mapped to which sampler uniform. glActiveTexture使用的采样器制服和纹理单元之间的对应关系显然无法用 opengl 查询,而且我找不到关于如何找到哪个纹理单元映射到哪个采样器制服的好的文档。 Here is what I have been able to find:这是我能够找到的:

  • If there is only sampler uniform in a program, then it is mapped to gl_TEXTURE0如果程序中只有采样器uniform,则映射到gl_TEXTURE0
  • If there are multiple sampler uniforms in a single program stage, then they are mapped in the order they are declared in the shader.如果在单个程序阶段中有多个采样器制服,则它们将按照它们在着色器中声明的顺序进行映射。
  • If the vertex and fragment shaders have disjoint sets of sampler uniforms, then the samplers in the vertex shader come first and are followed by the samplers in the fragment shader.如果顶点着色器和片段着色器具有不相交的采样器统一集,则顶点着色器中的采样器首先出现,然后是片段着色器中的采样器。
  • This behavior appears to be defined by the specification.这种行为似乎是由规范定义的。

So for example if the vertex shader defines:例如,如果顶点着色器定义:

uniform sampler2D color;

And the fragment shader defines:片段着色器定义:

uniform sampler2D tex;
uniform sampler2D norm;

Then color gets mapped to gl_TEXTURE0 , tex gets mapped to gl_TEXTURE1 , and norm gets mapped to gl_TEXTURE2 .然后color被映射到gl_TEXTURE0tex被映射到gl_TEXTURE1norm被映射到gl_TEXTURE2 But if instead the vertex shader defines:但是如果顶点着色器定义为:

uniform sampler2D norm;

Then it is not clear how the different textures get mapped.然后不清楚如何映射不同的纹理。 This is additionally complicated by the possibility of having layout qualifiers or separate shader stages.由于具有布局限定符或单独的着色器阶段的可能性,这也变得更加复杂。

I can't seem to find documentation on this anywhere.我似乎无法在任何地方找到有关此的文档。 Everything I know about it either comes from my own experimentation or answers on Stackoverflow or the OpenGL forum.我所知道的一切要么来自我自己的实验,要么来自 Stackoverflow 或 OpenGL 论坛上的答案。 Does anyone know of a comprehensive set of rules for how this works in all possible cases, or a way to query the texture unit that a sampler corresponds to?有没有人知道在所有可能的情况下如何工作的一套全面规则,或者查询采样器对应的纹理单元的方法?

Here is what I have been able to find:这是我能够找到的:

  • If there is only sampler uniform in a program, then it is mapped to gl_TEXTURE0如果程序中只有采样器uniform,则映射到gl_TEXTURE0
  • If there are multiple sampler uniforms in a single program stage, then they are mapped in the order they are declared in the shader.如果在单个程序阶段中有多个采样器制服,则它们将按照它们在着色器中声明的顺序进行映射。
  • If the vertex and fragment shaders have disjoint sets of sampler uniforms, then the samplers in the vertex shader come first and are followed by the samplers in the fragment shader.如果顶点着色器和片段着色器具有不相交的采样器统一集,则顶点着色器中的采样器首先出现,然后是片段着色器中的采样器。
  • This behavior appears to be defined by the specification.这种行为似乎是由规范定义的。

None of this is true.这一切都不是真的。 OK, the first one is true, but only by accident.好吧,第一个是真的,但只是偶然。

All uniform values which are not initialized in the shader are initialized to the value 0. The spec makes this quite clear:所有未在着色器中初始化的统一值都被初始化为值 0。规范对此非常清楚:

Any uniform sampler or image variable declared without a binding qualifier is initially bound to unit zero.任何没有绑定限定符声明的统一采样器或图像变量最初都绑定到零单元。

A sampler uniform's value is the integer index of the texture unit it represents.采样器统一的值是它代表的纹理单元的整数索引。 So a value of 0 corresponds to GL_TEXTURE0 .所以 0 值对应于GL_TEXTURE0 All uninitialized sampler uniforms should have a value of 0.所有未初始化的采样器制服的值都应为 0。

If the behavior you describe is happening, then that implementation is in violation of the OpenGL specification.如果您描述的行为正在发生,则该实现违反了 OpenGL 规范。

Unless you use the layout(binding = ) syntax to assign a uniform's texture unit, you must manually in your OpenGL code assign each sampler uniform a value for its texture unit.除非您使用layout(binding = )语法来分配统一的纹理单元,否则您必须在 OpenGL 代码中手动为每个采样器统一分配一个纹理单元的值。 This is done by setting its uniform value, just like any other integer uniform: you call glUniform1i with the location corresponding to that uniform.这是通过设置它的统一值来完成的,就像任何其他整数统一:你调用glUniform1i与对应于该统一的位置。 So if you want to associate it with texture image unit index 4, you call glUniform1i(..., 4) , where ... is the uniform location for that uniform.因此,如果您想将它与纹理图像单元索引 4 相关联,您可以调用glUniform1i(..., 4) ,其中...是该制服的统一位置。

You have to set the index of the texture unit to sampler uniform (similar as setting the value of a uniform variable of type int ).您必须将纹理单元的索引设置为采样器统一(类似于设置int类型的统一变量的值)。 eg value 1 for GL_TEXTURE1 .例如GL_TEXTURE1值为 1 。

See OpenGL 4.6 API Compatibility Profile Specification;请参阅OpenGL 4.6 API 兼容性配置文件规范; 7.10 Samplers; 7.10 取样器; page 154 : 第 154 页

Samplers are special uniforms used in the OpenGL Shading Language to identify the texture object used for each texture lookup.采样器是 OpenGL 着色语言中使用的特殊统一体,用于标识用于每个纹理查找的纹理对象。 The value of a sampler indicates the texture image unit being accessed.采样器的值表示正在访问的纹理图像单元。 Setting a sampler's value to i selects texture image unit number i .将采样器的值设置为i选择纹理图像单元编号i

eg例如

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

Since GLSL version 4.2 this can be done in the fragment shader by specifying binding points - See OpenGL Shading Language 4.20 Specification - 4.4.4 Opaque-Uniform Layout Qualifiers;从 GLSL 4.2 版开始,这可以通过指定绑定点在片段着色器中完成 - 请参阅OpenGL Shading Language 4.20 Specification - 4.4.4 Opaque-Uniform Layout Qualifiers; page 60 : 第 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM