带有 GLSL 的 OpenGL 4.5 中的无限网格问题

问题描述 投票:0回答:2

我一直在玩弄无限网格,使用 OpenGL 4.5 中的着色器,按照本教程here。由于本教程是为 Vulkan 和更高版本的 GLSL(我使用的是 450 核)编写的,因此我不得不将顶点移出顶点着色器并移入应用程序代码中。我正在使用元素缓冲区渲染四边形,所以我的顶点最终看起来像这样:

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

我已经设法让网格完全正常工作,但它有两个我无法弄清楚的问题:

  1. 绘制在网格顶部的对象随着地平线向上移动而被剪裁。这感觉就像 z-fighting,但我不是 100% 确定为什么会发生这种情况,看看立方体是如何在网格之后呈现的。
  2. 网格的底面是完全实心的。这也让我感到困惑,因为基于片段着色器,网格线之间的空间应该是完全透明的……但它们看起来完全是实心的。

以下是正在发生的事情的一些示例图像: 看到立方体被切成两半。如果我向下移动相机,立方体的其余部分就会慢慢出现。相反,如果我向上移动相机,立方体最终会完全消失。

这是网格的底面。我应该能够通过网格看到立方体,但网格的行为就像一个实体对象。

有人知道我做错了什么吗?我应该在应用程序中启用某些东西吗?作为参考,我目前启用了此功能:

glEnable(GL_MULTISAMPLE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
c++ opengl glsl glm-math opengl-4
2个回答
1
投票

混合仅在禁用深度测试或对象从后向前绘制时有效。启用深度测试(使用其默认功能

GL_LESS
)时,较近的物体胜过较远的物体。即使片段的 alpha 通道为 0,片段也会影响深度缓冲区和深度测试。因此,如果先前绘制了更近的透明片段,则会丢弃更远的片段。
您只有一个带有透明片段的对象,即网格。要解决您的问题,只需在立方体后绘制网格:

  • 启用深度测试
  • 绘制立体物体(立方体)
  • 启用混合
  • 绘制网格

0
投票

我发现了问题所在。我也跟着tutorial,我有一个类似的问题。问题在于 gl_FragDepth。 OpenGL 测试深度的方法是让值介于 -1 和 1 之间,而 DirectX 12 在 0 和 1 之间进行测试。该算法基于 0 和 1 之间的深度范围的想法。为了解决这个问题,您可以像这样更改片段深度的计算:

// gl_FragDepth = computeDepth(fragPos3D);
gl_FragDepth = ((gl_DepthRange.diff * computeDepth(fragPos3D)) +
                gl_DepthRange.near + gl_DepthRange.far) / 2.0;

请查看这篇文章了解更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.