在 OpenGL 中绑定多个纹理无法正常工作

binding multiple texture in OpenGL does not work correctly

我厌倦了绑定多个纹理 当我有 2 个或更多纹理时,我有一些奇怪的东西,它们相互叠加

使用 GPU 时出现此问题:NVIDIA GeForce RTX 3070 笔记本电脑 GPU/PCIe/SSE2 和 openGL 版本 4.6 是这样的:

但使用 GPU 时:AMD Radeon(TM) 图形非常好像这样

main.cpp

shaderProgram.bind();
const int NUMBER_OF_TEXTURE = textures.size();
auto sample = new int[NUMBER_OF_TEXTURE];
for (int i = 0; i < NUMBER_OF_TEXTURE; i++)
    sample[i] = i;

shaderProgram.setUniform1iv("u_Textuers", NUMBER_OF_TEXTURE, sample);
delete[] sample;

while (!glfwWindowShouldClose(window))
{
    processInput(window);

    Renderer::clear();
    shaderProgram.bind();

    for (int i = 0; i < NUMBER_OF_TEXTURE; i++)
    {
        textures[i].Bind(i);
    }
    render.draw(shaderProgram);
    GLCall(glBindTexture(GL_TEXTURE_2D, 0))


    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

    glfwSwapBuffers(window);
    glfwPollEvents();
}

Texture.cpp

Texture::Texture(const FxrDataStructures::Image& image)
    :m_RendererID(0), m_LocalBuffer(nullptr),
    m_Width(0), m_Height(0), m_BPP(0)
{
    GLCall(glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID));
    GLCall(glBindTexture(GL_TEXTURE_2D, m_RendererID));

    // set the texture wrapping/filtering options (on the currently bound texture object)
    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR))
    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR))
    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE))
    GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE))

    m_Width = image.getWidth();
    m_Height = image.getHeight();
    m_BPP = image.getBitDepth();

    cv::Mat mat = image.img;
    cv::flip(mat, mat, 0);
    m_LocalBuffer = mat.ptr();
    if (m_LocalBuffer)
    {
        GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer))
        //GLCall(glGenerateMipmap(GL_TEXTURE_2D))
    }
    else
    {
        LOG_DEBUG("Failed to load texture ");
    }
    GLCall(glBindTexture(GL_TEXTURE_2D, 0))

}

void Texture::Bind(unsigned int slot) const
{

    GLCall(glBindTextureUnit(slot, m_RendererID))
}

片段着色器

in float IndexMaterial;

uniform sampler2D u_Textuers[32];
void main()
{
    float diff;
    const int index = int(IndexMaterial);

    FragColor = vec4(texture(u_Textuers[index], TexCoord));
}

我想说这与 int-to-float 转换有关。貌似NVIDIA GPU在插值IndexMaterial时加入了一点随机噪声,而AMD GPU则没有。

尝试对 IndexMaterial 使用平面着色。这将导致 GPU 使用来自一个顶点的值,而不是在顶点之间进行插值:

flat in float IndexMaterial;

参见:"flat" qualifier in glsl?

您也可以将 IndexMaterial 从 float 更改为 int,因为它没有充分的理由成为 float。