当前位置: 首页 > 知识库问答 >
问题:

OpenGL-Java-渲染问题,多边形闪烁和消失

呼延臻
2023-03-14

我在使用LWJGL和GLSL着色器在Java中渲染Master Cheif时遇到了一些问题,其中存在一些闪烁、多边形不相似和奇怪的颜色。我的一生都不知道为什么。

着色器:https://github.com/marko5049/LucidEngine/tree/master/src/res/shaders

主着色器:LightingMain ShdaowMapping Smapler过滤器

所有代码:https://github.com/marko5049/LucidEngine

静态网格:

public void addVertices(Vertex[] vertices, int[] indices, boolean calcNorm) {
    if(calcNorm) {
        vertices = calcNormals(vertices, indices);
    }

    handler.setSize(indices.length);
    EngineCore.polycount += indices.length/3;

    glBindBuffer(GL_ARRAY_BUFFER, handler.getVbo());
    glBufferData(GL_ARRAY_BUFFER, Util.createFlippedBuffer(vertices), GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handler.getIbo());
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, Util.createFlippedBuffer(indices), GL_STATIC_DRAW);
}

private void finalDraw(int typeIndex) {
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glEnableVertexAttribArray(3);

    glBindBuffer(GL_ARRAY_BUFFER, handler.getVbo());
    glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0);
    glVertexAttribPointer(1, 2, GL_FLOAT, false, Vertex.SIZE * 4, 12);
    glVertexAttribPointer(2, 3, GL_FLOAT, false, Vertex.SIZE * 4, 20);
    glVertexAttribPointer(3, 3, GL_FLOAT, false, Vertex.SIZE * 4, 32);
    glVertexAttribPointer(3, 3, GL_FLOAT, false, Vertex.SIZE * 4, 44);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handler.getIbo());
    glDrawElements(typeIndex, handler.getSize(), GL_UNSIGNED_INT, 0);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
    glDisableVertexAttribArray(3);
}

共有1个答案

姬英耀
2023-03-14

您在示例图像中描述的和显示的内容是通常称为“深度战斗”或“z-fighting”的问题的典型症状。这是由深度缓冲区的精度限制引起的。

此问题最常见的情况是,如果深度缓冲区覆盖的范围很大,并且场景包含具有非常相似的深度值的面。

例如,想象一个多边形a在世界空间中稍微位于多边形B的前面。在应用所有变换后,多边形A和多边形B的像素可以最终具有相同的深度值,并将结果深度四舍五入到可用深度缓冲精度。根据绘制顺序,在这种情况下,多边形A或多边形B的像素将可见。典型的结果是,多边形a和多边形B的像素混合将显示多边形a应覆盖多边形B的位置。

有多种方法可以解决此问题:

    < li >缩小深度范围。在标准透视投影中,这由近平面距离和远平面距离控制,其中相对远/近值是临界量。哪些值会导致深度冲突在很大程度上取决于场景和深度缓冲精度。最安全的做法是保持相对值尽可能小。在大多数情况下,高达100左右的值很少会导致问题,而1000或更高的值可能会导致问题。 < li >提高深度缓冲精度。最常见的深度缓冲区大小是16位和24位,许多GPU都支持这两种大小。如果事情变得有问题,选择至少24位。根据硬件和OpenGL版本,可能会提供更高分辨率的深度缓冲区。 < li >避免渲染深度几乎相同的多边形。要么移除深度非常接近可见多边形的隐藏多边形,要么至少将它们移动得更远。

如果上述还不够,解决方案就会变得更加复杂。在某些情况下,确实存在具有较大深度范围的几何图形,这些几何体必须同时可见。处理这些(相对罕见)情况的方法包括对数深度缓冲区和多通道渲染方法。

请注意,我的答案纯粹是关于世界空间中原始多边形具有不同深度的情况。如果绘制具有完全相同深度的多边形(即共面多边形),则几乎总是会产生深度冲突,需要使用其他方法避免这种情况。因为这看起来不像这里的场景,所以我故意没有涵盖它。

 类似资料:
  • 我们当前的任务要求我们在openGL中使用较旧的固定管道方法。我们使用的是LWJGL 2.9.3。下面的代码显示一个三角形。问题是,它会疯狂地闪烁。显示器。swapBuffers()方法不会引发异常,并且无论是否包含它都没有任何区别。我根据这个问题创建了这个示例: gluPerspective、GluViewport、gluLookAt以及GL_投影和GL_MODELVIEW矩阵 编辑 还有一件事

  • 背景信息: 我正在使用OpenGL和LWJGL 3在屏幕上绘制一些四边形。我需要知道鼠标何时在四轴上。当我将四边形渲染到屏幕上时,我使用OpenGL坐标,X和Y的范围是从-1到1,而(0,0)在屏幕的中心。当我得到我使用的鼠标位置时 这给了我从0到窗口宽度或高度的坐标,在左上角(标题栏下方)有(0,0)。然后取鼠标坐标并计算OpenGL坐标。 例如,如果我的窗口大小为(800,600),而我的鼠标

  • 我有一个标题,我想显示一个图像在它的右边,当鼠标在标题上。 > 我正在将变量editMode的状态设置为true/false 然后我使用onMouseOver和onMouse事件有条件地呈现图像。 现在,当我悬停在标题上时,编辑模式设置为true,图像显示出来,当我将光标移出标题时,editMode设置为false,图像消失。 我正在维护一个变量editMode的状态,该状态被设置为true/fa

  • 我正在使用LWJGL 2.8.5开发一个3D可视化应用程序。在阅读了项目主页上的第一个教程后,我还阅读了一本OpenGL书籍,进行了更深入的分析。我看到OpenGL中的典型过程是在init函数中绘制场景,然后简单地在一个循环中调用显示的更新。 但是,当我尝试使用LWJGL时,我在显示屏中得到了闪烁效果。消除闪烁的唯一方法是在显示更新周期中重绘场景。为什么会发生这种情况? 为了更好地解释我的问题,我

  • 我已经试着让这段代码工作了一段时间,但我仍然不知道我做错了什么。(LWJGL-Java) 我曾尝试在网上查看其他人的代码,但我找不到任何重大区别。事实上,我学会了将OpenGL与C结合使用,所以我的大脑可能会被它卡住,这可能就是我找不到错误的原因。 这是init(调用一次) 这是渲染函数: 着色器: 顶点: Framgent公司:

  • (这是我第二次问这个问题了。上次我得到了一个没有解决问题的答案(那里的答案提到了我试图修复这个问题时偶然留下的一点代码)。我还稍微改变了问题本身——我改变了代码的顺序,把我认为错误更高的部分放在前面,并补充说我正在使用macOS,这可能是它不起作用的原因)。 所以,我刚刚开始学习LWJGL 3,我混合使用了一些教程和示例代码来制作一些东西,应该使用VAOs和VBOs将矩形渲染到洋红屏幕上。没有错误