深度测试丢弃自定义帧缓冲区上的片段

Depth test discards fragments on custom framebuffer

在我的程序中,我将多个矩阵渲染到不同的帧缓冲区。最后,我将帧缓冲区创建的纹理渲染为三个 2D 四边形。问题是深度测试丢弃了自定义帧缓冲区的所有片段,除了第一个被渲染的片段。

这里我初始化帧缓冲区:

unsigned int* framebufferArray = new unsigned int[(input_view.size()+output_view.size()+1)];
unsigned int* framebufferTextureArray = new unsigned int[(input_view.size() + output_view.size() + 1)];
for (int i = 0; i < (input_view.size()+output_view.size()+1); ++i)
{
    unsigned int framebuffer;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    unsigned int fBufferTexture;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    unsigned int fBufferTexture;
    glGenTextures(1, &fBufferTexture);
    glBindTexture(GL_TEXTURE_2D, fBufferTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window_width, window_height, 0, GL_RGB, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fBufferTexture, 0);

    unsigned int rbo;
    glGenRenderbuffers(1, &rbo);
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, window_width, window_height); // use a single renderbuffer object for both a depth AND stencil buffer.
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo); // now actually attach it
    // now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        printf("ERROR::FRAMEBUFFER:: Framebuffer is not complete!");
    framebufferArray[i] = framebuffer;
    framebufferTextureArray[i] = fBufferTexture;
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
}

我在这里渲染矩阵:

for (int i = 0; i < input_view.size(); ++i)
    {
        float alphaFactor = 1;

        glBindFramebuffer(GL_FRAMEBUFFER, framebufferArray[i + 1]);
        glClearColor(bgColor[0], bgColor[1], bgColor[2], 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glDisable(GL_BLEND);
        glEnable(GL_DEPTH_TEST);
        glDepthMask(GL_TRUE);

        glUseProgram(solidShaderID);
        std::vector<float> Cachecolor = { CacheColorInfo[cacheLayerCount - 1][0], CacheColorInfo[cacheLayerCount - 1][1], CacheColorInfo[cacheLayerCount - 1][2] };

        glBindTexture(GL_TEXTURE_2D, solidTexture);
        mat4 translationMatrix = glm::translate(mat4(1.0f), glm::vec3(ThreadTranslateVector[0], ThreadTranslateVector[1], ThreadTranslateVector[2] + 6));
        glUniformMatrix4fv(glGetUniformLocation(solidShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
        glUniform3fv(glGetUniformLocation(solidShaderID, "tint"), 1, &Cachecolor[0]);
        glUniform1f(glGetUniformLocation(solidShaderID, "focusFac"), focusLayerFac[cacheLayerCount]);

        glBindVertexArray(inputViewVAOs[i][1]);
        glDrawArrays(GL_TRIANGLES, 0, inputViewVertexCountInfo[i][1] * 3);
        glBindVertexArray(0);

        glDepthMask(GL_FALSE);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glUseProgram(transShaderID);
        glBindTexture(GL_TEXTURE_2D, transparentTexture);
        translationMatrix = glm::translate(mat4(1.0f), vec3(0, matsizeN, 0));
        glUniformMatrix4fv(glGetUniformLocation(transShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);
        glUniform3fv(glGetUniformLocation(transShaderID, "tint"), 1, &matColor[0]);
        glUniform1f(glGetUniformLocation(transShaderID, "focusFac"), focusLayerFac[cacheLayerCount]);
        glUniform1fv(glGetUniformLocation(transShaderID, "alphaFac"), 1, &alphaFactor);

        glBindVertexArray(inputViewVAOs[i][0]);
        glDrawArrays(GL_TRIANGLES, 0, inputViewVertexCountInfo[i][0] * 3);
        glBindVertexArray(0);
    }

这里我渲染了三个四边形:

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    glClearColor(bgColor[0], 0.3, bgColor[2], 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_BLEND);


    glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[0]);
    glUseProgram(matrix2dShaderID);
    mat4 translationMatrix = glm::mat4(1.0f);
    //translationMatrix = glm::translate(translationMatrix, glm::vec3((float)(window_width - 200) / (float)window_width, 0, 0));
    translationMatrix = glm::translate(translationMatrix, glm::vec3(0,0.6,0));
    translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize/(float)window_height,(float)viewSize/(float)window_height,1));
    glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);

    glBindVertexArray(quadVAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);

    glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[1]);
    glUseProgram(matrix2dShaderID);
    translationMatrix = glm::mat4(1.0f);
    translationMatrix = glm::translate(translationMatrix, glm::vec3(0, -0.6, 0));
    translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize / (float)window_height, (float)viewSize / (float)window_height, 1));
    glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);

    glBindVertexArray(quadVAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);

    glBindTexture(GL_TEXTURE_2D, framebufferTextureArray[2]);
    glUseProgram(matrix2dShaderID);
    translationMatrix = glm::mat4(1.0f);
    translationMatrix = glm::translate(translationMatrix, glm::vec3(0,0, 0));
    translationMatrix = glm::scale(translationMatrix, glm::vec3((float)viewSize / (float)window_height, (float)viewSize / (float)window_height, 1));
    glUniformMatrix4fv(glGetUniformLocation(matrix2dShaderID, "translation"), 1, GL_FALSE, &translationMatrix[0][0]);

    glBindVertexArray(quadVAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);

这是启用深度测试的输出:

并且禁用了深度测试:

似乎深度测试只是丢弃了第一个帧缓冲区之后的所有内容。

问题是由于禁用写入深度缓冲区引起的:

glDepthMask(GL_FALSE);

glDepthMask sets a global state and specifies whether a depth buffer is enabled or disabled for writing. This also effects operations glClear。如果深度缓冲区被禁止写入,那么深度缓冲区也不能被清除。
请注意,状态是全局的,并且会一直保留到再次更改为止。当调用 glClear 时,将评估 glDepthMask 标志的当前状态。

启用写入深度缓冲区,清除前:

glBindFramebuffer(GL_FRAMEBUFFER, 0);

glClearColor(bgColor[0], 0.3, bgColor[2], 1.0f);

glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);