c++ - 将纹理传递给 GLSL 着色器而不使用统一?

标签 c++ opengl glsl

为了给我的着色器提供纹理,我使用了 Sampler2D 类型的制服,但是,由于我有很多顶点都使用不同的纹理和不同的着色器,所以当我通过每个顶点都是正确的纹理时,我会遇到瓶颈。所以我尝试使用一个使用纹理的全局数组并将其作为布局传递给我的着色器:

layout (location = 6) in sampler2D aTexture;\n

问题是,我的着色器不会编译引发错误:
0(24) : error C7514: OpenGL does not allow varying of type sampler2D
0(24) : error C7554: OpenGL requires sampler variables to be explicitly declared as uniform

既然我们不能使用布局为着色器提供纹理,那么你们如何使用纹理来避开这些瓶颈?我被迫使用制服?

最佳答案

简而言之:不,您不能使用纹理采样器作为顶点输入。它们必须是统一的。

因此,有两种可能的解决方案,每种解决方案都更适合特定场景:

  • 如果你的每个几何体(你称之为顶点)都有不同的着色器代码,那么如果你的 super 着色器(渲染它们的一个着色器)非常重(大量的分支和函数调用)我建议你将它们分开超过一次抽奖。
    为此,您必须确保每个着色器程序彼此之间非常不同(例如,一些是不透明的,而另一些是透明的或经过 alpha 测试)。
    但是如果有些只有不同的贴图(比如有些有法线贴图,而另一些没有),那么我建议您在不使用分支的情况下回收代码,例如在没有法线贴图时使用 1x1 像素法线贴图
  • 如果您的每个几何体都有非常相似的着色器代码但不同的纹理,您可以使用数组纹理,它们对内存不友好(因为数组上的所有纹理都需要具有相同的大小)但您可以使用一个绘制调用来绘制它们:
  • 在 CPU 方面:阵列纹理像通常的 2D 纹理一样创建(只需使用 GL_TEXTURE_2D_ARRAY 进行创建和绑定(bind))
  • 加载到 GPU 时,您必须像 3D 纹理一样加载,即使用 glTexSubImage3D。您的 zoffset 表示纹理索引,数组
  • 上的每个元素的深度必须为 1
  • 在着色器方面,您使用 sampler2DArray 并像 3D 纹理一样对其进行采样,其中 Z 是纹理索引。

  • 这是代码的示例着色器片段:
    uniform sampler2DArray myArrayTexture;
    in vec2 texCoord;
    ...
    vec4 color1 = texture(myArrayTexture, vec3(texCoord, 0)); // sampling index 0
    vec4 color2 = texture(myArrayTexture, vec3(texCoord, 1)); // sampling index 1
    

    以下是将数组加载到 GPU 中的方法:
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, 1, format, type, dataAtIndex0);
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, width, height, 1, format, type, dataAtIndex1);
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 2, width, height, 1, format, type, dataAtIndex2);
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 3, width, height, 1, format, type, dataAtIndex3);
    ...
    

    关于c++ - 将纹理传递给 GLSL 着色器而不使用统一?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60099956/

    相关文章:

    glsl - gl_FragColor 和 glReadPixels

    c++ - 错误 C4716 : must return a value, 由实际返回值的函数抛出

    opengl - GLEW 和 CodeBlcks 的链接器问题

    python - 在 pyOpenGL 中对齐各个对象以创建更大的聚合对象

    c++ - 隧道着色器(从 WebGL 转换为 OpenGL)- 纹理坐标不匹配?

    opengl - OpenGL GLSL 中从 RGB 到 HSV

    c++ - 字符串与重复字符的排列(访问数组概念)

    c++ - 我得到一个 "string subscript out of range error"。我不明白为什么

    c++ - 如何在 C++ 中声明指向常量指针的指针?

    OpenGL:如何在不更改目标 alpha 的情况下进行 RGBA->RGBA 位图传输