OpenGL采样器二维数组

qlvxas9a  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(250)

我有一个sampler2D数组,如下所示:uniform sampler2D u_Textures[2];。我希望能够在同一个DrawCall中渲染更多的纹理(在本例中为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;
}

此外,它只在屏幕上绘制纹理2纹理。这是我的垂直属性:

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
    };

无论我如何挑战纹理索引,它只绘制了这两个纹理中的一个。

2ekbmq32

2ekbmq321#

不能使用片段着色器输入变量为纹理采样器数组编制索引。您必须使用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));
}

所有采样器类型的texture都是重载的。纹理坐标和纹理层不需要动态统一,但采样器阵列的索引必须动态统一。

需要明确的是,问题不在于采样器数组(问题不在于sampler2D u_Textures[2];)。问题在于索引。问题是v_texIndex不是动态一致的(问题是in float v_texIndex;)。当索引动态一致时(例如,uniform float v_texIndex;将起作用),它就会起作用。另外,规范只说结果是未定义的。因此,可能有一些系统可以让它发挥作用。

相关问题