Отрисовка отверстий с помощью stencil buffera

Всем привет пытаюсь реализовать отрисовку отверстий в ландшафте без геометрии. Как я понял для этих целей обычно юзают 2 объекта(заглушка и задник), но я пытаюсь реализовать одним цилиндром который торчит чуть выше плоскости. 1 vao - плоскость на 0 высоте, 2й - цилиндр верхняя грань которого на 0.01 выше плоскости

while (!glfwWindowShouldClose(window))
    {
        GLfloat currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        glStencilFunc(GL_ALWAYS, 1, 0xFF);
        glStencilMask(0x00);

        cam.camera_movement(window, deltaTime);

        glm::mat4 view = cam.view();

        lightingShader.use();

        lightingShader.setVec3("viewPos", cam.position[0], cam.position[1], cam.position[2]);
        lightingShader.setMat4("matrix", projection * view);
        lightingShader.setVec3("light.position", 1.2f, 1.0f, 2.0f);
        lightingShader.setVec3("light.ambient", 0.5f, 0.5f, 0.5f);
        lightingShader.setVec3("light.diffuse", 0.5f, 0.5f, 0.5f);
        lightingShader.setVec3("light.specular", 0.5f, 0.5f, 0.5f);
        lightingShader.setVec3("material.ambient", 0.0f, 0.2f, 0.0f);
        lightingShader.setVec3("material.diffuse", 0.1f, 0.1f, 0.1f);
        lightingShader.setVec3("material.specular", 0.1f, 0.1f, 0.1f);
        lightingShader.setFloat("material.shininess", 1);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, diffuseMap);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, specularMap);
        glBindVertexArray(VAO1);
        glDrawArrays(GL_TRIANGLES, 0, vertices_plane.size());
        
        glStencilMask(0xFF);
        emptyShader.use();
        emptyShader.setMat4("matrix", projection * view);
        glBindVertexArray(VAO2);
        glDrawArrays(GL_TRIANGLES, 0, cylinder_vertices.size());
        
        glStencilFunc(GL_EQUAL, 1, 0xFF);
        glDisable(GL_DEPTH_TEST);
        glStencilMask(0x00);
        lightingShader.use();
        lightingShader.setVec3("light.diffuse", 10.0f, 10.0f, 10.0f);
        lightingShader.setVec3("light.ambient", 10.0f, 10.0f, 10.0f);
        glDrawArrays(GL_TRIANGLES, 0, cylinder_vertices.size());
        glBindVertexArray(0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

Сначала я отрисовываю ландшафт, затем шейдером без отрисовки прохожусь по цилиндру и заполняю буфер трафарета 1ми в местах где его видно(должен получиться немного неправильный эллипс на месте части цилиндра которая выступает из плоскости) а после пытаюсь рендерить задник цилиндра в пикселях значения буфера для которых равно единице. Возникают 2 проблемы.

  1. Когда я рендерю задник на последнем этапе оказывается что единицами буфер заполнен не в местах где видно выступающую часть цилиндра, а по всей поверхности цилиндра, введите сюда описание изображения

хотя в glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); я указываю замену только в случае если фрагмент прошел оба теста и часть скрытая под плоскостью по идее не должна записываться в буфер. Как буфер должен выглядеть по моему мнениювведите сюда описание изображения

Как он выглядит исходя из результатов кодавведите сюда описание изображения

2) Заднюю часть цилиндра я хочу отрисовать поменяв на последней отрисовке depth-функцию на GL_GREATER, но в этом случае экран вообще становится полностью черным как ни меняй обзор.


Ответы (0 шт):