OpenGL采样器2D数组。

4

我有一个看起来像这样的sampler2D数组:uniform sampler2D u_Textures[2];。 我想在同一次绘制中渲染更多纹理(在这种情况下是2个)。 在我的片元着色器中,如果我将颜色输出值设置为例如红色,它会显示给我2个红色方块,这使我认为绑定纹理时出了些问题。

我的代码:

Texture tex1("Texture/lin.png");
tex1.Bind(0);
Texture tex2("Texture/font8.png");
tex2.Bind(1);

auto loc = glGetUniformLocation(sh.getRendererID(), "u_Textures");
GLint samplers[2] = { 0, 1 };
glUniform1iv(loc, 2, samplers);

void Texture::Bind(unsigned int slot) const {
    glActiveTexture(slot + GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_RendererID);
}

这是我的片段着色器:

#version 450 core
layout(location = 0) out vec4 color;

in vec2 v_TexCoord;
in float v_texIndex;

uniform sampler2D u_Textures[2];

void main() 
{
    int index = int(v_texIndex);
    vec4 texColor = texture(u_Textures[index], v_TexCoord);
    if (texColor.a == 0.0) {
        // this line fills the a = 0.0f pixels with the color red  
        color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
    }
    else color = texColor;
}

此外,它只会在屏幕上绘制tex2纹理。 这是我的顶点属性:

float pos[24 * 2] = {
        // position xy z    texture coordinate, texture index
        -2.0f, -1.5f, 0.0f,     0.0f, 0.0f, 0.0f,
        -1.5f, -1.5f, 0.0f,     1.0f, 0.0f, 0.0f,
        -1.5f, -2.0f, 0.0f,     1.0f, 1.0f, 0.0f, // right side bottom
        -2.0f, -2.0f, 0.0f,     0.0f, 1.0f, 0.0f,

        0.5f, 0.5f, 0.0f,   0.0f, 0.0f, 1.0f,
        1.5f, 0.5f, 0.0f,   1.0f, 0.0f, 1.0f, 
        1.5f, 1.5f, 0.0f,   1.0f, 1.0f, 1.0f,
        0.5f, 1.5f, 0.0f,   0.0f, 1.0f, 1.0f
    };

无论我如何更改纹理索引,它只会绘制其中的1个纹理。
1个回答

5

您不能使用片段着色器输入变量来索引纹理采样器数组,必须使用 sampler2DArray (GL_TEXTURE_2D_ARRAY)而不是 sampler2D (GL_TEXTURE_2D) 数组。

int index = int(v_texIndex);
vec4 texColor = texture(u_Textures[index], v_TexCoord);
因为v_texIndex是片元着色器的输入变量,因此不属于动态一致表达式,所以这是未定义行为。请参见GLSL 4.60规范-4.1.7.不透明类型

[...]纹理组合采样器类型是不透明类型,[...]当在着色器中聚合成数组时,它们只能用动态一致的整数表达式索引,否则结果是未定义的。


使用sampler2DArray的示例:

#version 450 core
layout(location = 0) out vec4 color;

in vec2 v_TexCoord;
in float v_texIndex;

uniform sampler2DArray u_Textures;

void main() 
{
    color = texture(u_Textures, vec3(v_TexCoord.xy, v_texIndex));
}

纹理对于所有采样器类型都进行了过载。纹理坐标和纹理层不需要动态一致,但是采样器数组中的索引必须是动态一致的。


要明确的是,问题不在采样器数组上(问题不在 sampler2D u_Textures[2]; 上)。问题在于索引。问题在于 v_texIndex 不是动态统一的(问题在于 in float v_texIndex;)。当索引动态统一时它可以工作(例如 uniform float v_texIndex; 将会工作)。同时规范只是说明结果是未定义的。因此可能存在一些系统它能够工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接