c++openglglslglm-mathopengl-4

Issues with infinite grid in OpenGL 4.5 with GLSL


I've been toying around with an infinite grid using shaders in OpenGL 4.5, following this tutorial here. Since the tutorial was written for Vulkan and a higher version of GLSL (I'm using 450 core), I had to move the vertices out of the vertex shader and into the application code. I'm rendering the quad using an element buffer, so my vertices ended up looking like this:

std::vector<glm::vec3> points{glm::vec3{-1, -1, 0},
                              glm::vec3{1, -1, 0},
                              glm::vec3{1, 1, 0},
                              glm::vec3{-1, 1, 0}};

std::vector<GLuint> indices{0, 1, 2, 2, 3, 0};

// Render like this:
glBindVertexArray(m_vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

I've managed to get the grid fully working, but it has two issues that I can't figure out:

  1. Objects that are drawn on top of the grid are getting clipped as the horizon moves up. This feels like z-fighting, but I'm not 100% sure why this would happen, seeing how the cube is being rendered after the grid.
  2. The underside of the grid is completely solid. This one also confuses me, because based on the fragment shader, the spaces in between the grid lines should be fully transparent... and yet they appear to be completely solid.

Here are some sample images of what is happening: enter image description here See that the cube is sliced in half. If I move the camera down, the rest of the cube will slowly appear. Conversely, if I move the camera up, the cube eventually disappears completely.

enter image description here This is the underside of the grid. I should be able to see the cube through the grid, but the grid behaves like a solid object.

Does anyone have any ideas of what I'm doing wrong? Should I be enabling something in the application? For reference, I currently have this enabled:

glEnable(GL_MULTISAMPLE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Solution

  • Blending only works when the Depth Test is disabled or the objects are drawn from back to front. When the depth test is enabled (with its default function GL_LESS) closer objects win against more distant objects. Even if a fragment's alpha channel is 0, the fragment affects the depth buffer and the depth test. Thus, a more distant fragment is discarded if a closer, transparent fragment was previously drawn.
    You only have one object with transparent fragments, the grid. To solve your problem, just draw the grid after the cube: