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

标签 opengl glsl shader

glActiveTexture 使用的采样器制服和纹理单元之间的对应关系显然不能用 opengl 查询,而且我找不到关于如何找到哪个纹理单元映射到哪个采样器统一的好的文档。这是我能够找到的:

  • 如果程序中只有采样器uniform,则映射到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 论坛上的答案。有没有人知道在所有可能的情况下如何工作的全面规则,或者查询采样器对应的纹理单元的方法?

    最佳答案

    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
    • 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.


    这一切都不是真的。好吧,第一个是真的,但只是偶然。

    所有未在着色器中初始化的统一值都被初始化为值 0。规范对此非常清楚:

    Any uniform sampler or image variable declared without a binding qualifier is initially bound to unit zero.



    采样器统一的值是它代表的纹理单元的整数索引。所以值 0 对应于 GL_TEXTURE0 .所有未初始化的采样器制服的值都应为 0。

    如果您描述的行为正在发生,则该实现违反了 OpenGL 规范。

    除非你使用 layout(binding = )语法来分配统一的纹理单元,您必须在 OpenGL 代码中手动为每个采样器统一分配一个纹理单元的值。这是通过设置它的统一值来完成的,就像任何其他整数统一一样:你调用 glUniform1i与那个制服对应的位置。所以如果你想把它与纹理图像单元索引 4 相关联,你可以调用 glUniform1i(..., 4) , 其中 ...是该制服的制服位置。

    关于opengl - opengl中纹理单元和采样器制服的对应关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54931941/

    相关文章:

    unity-game-engine - Unity3D,圆化盒子、立方体的边缘?

    c++ - 获取表面光属性

    c# - OpenGL - 单 channel 立方体贴图不产生输出

    opengl - GLSL 法线的奇怪效果

    java - 在着色器中使用 alpha 测试的 OpenGL ES 2.0 透明度

    opengl - glsl 输出和输入的命名约定

    c++ - 为什么glsl '#version'定义给我一个错误?

    c++ - Qt 和 OpenGL : render a 2D texture

    python - OpenGL:模型在 python 中加载时看起来不正确

    c++ - 在 imageStore() 之后为 3D 纹理生成 MipMap 级别