OpenGL-Java-渲染问题,多边形闪烁并消失 [英] OpenGL - Java - Rendering Issue, Polygons flickering and disappearing

查看:116
本文介绍了OpenGL-Java-渲染问题,多边形闪烁并消失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用LWJGL和GLSL着色器在Java中渲染Master Cheif时遇到了一些麻烦,其中有些闪烁,多边形消失和奇怪的颜色.对于我的一生,我不知道为什么.

I'm having some trouble with rendering Master Cheif in Java using LWJGL and GLSL shaders where the is some flickering, dissapearing of polygons and strange colouring. And for the life of me I can't figure out why.

它应该是什么样的:

What it should look like:

当我稍微移动相机时,它看起来像什么:

What it does look like when I move the camera a little:

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

MainShaders: 照明基础 Shdaow映射 斯马普勒 过滤器

MainShaders: LightingMain ShdaowMapping Smapler Filters

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

StaticMesh:

StaticMesh:

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

推荐答案

您描述并显示在示例图像中的内容是该问题的典型症状,通常被称为深度战斗"或"

What you describe and is shown in your sample images are typical symptoms of a problem that is often called "depth fighting" or "z-fighting". This is caused by precision limitations of the depth buffer.

最常见的情况是深度缓冲区所覆盖的范围较大,并且场景中包含深度值非常相似的多边形.

The most common scenario where this becomes an issue is if the range covered by the depth buffer is large, and the scene contains polygons with very similar depth values.

例如,描绘一个在世界空间中稍微位于多边形B前面的多边形A.应用所有转换后,来自多边形A和多边形B的像素最终可以具有相同的深度值,并且将得到的深度舍入为可用的深度缓冲区精度.根据绘制顺序,在这种情况下,来自多边形A或多边形B的像素将可见.典型的结果是,来自多边形A和多边形B的像素混合会显示出多边形A应该覆盖多边形B的位置.

For example, picture a polygon A that is slightly in front of polygon B in world space. Pixels from polygon A and polygon B can end up with the same depth value after all transformations are applied, and the resulting depth is rounded to the available depth buffer precision. Depending on the order of drawing, the pixel from polygon A or polygon B will be visible in this case. The typical result is that a mix of pixels from polygon A and polygon B will show up where polygon A should cover polygon B.

有多种解决方法:

  • 缩小深度范围.在标准透视投影中,这由近平面距离和远平面距离控制,其中相对远/近值是关键量.哪个值引起深度冲突,这在很大程度上取决于场景和深度缓冲区的精度.最安全的选择是保持相对值尽可能小.在大多数情况下,值大约为100时,很少会引起问题,而值1000和更高的值会开始引起问题.
  • 提高深度缓冲区的精度.最常见的深度缓冲区大小是16位和24位,许多GPU都支持.如果出现问题,请至少选择24位.根据硬件和OpenGL版本的不同,可能会提供更高分辨率的深度缓冲区.
  • 避免渲染深度几乎相同的多边形.要么删除深度与可见多边形非常接近的隐藏多边形,要么至少将它们移得更远.

如果以上还不够,解决方案将变得更加复杂.在某些情况下,确实存在深度范围很大且必须同时可见的几何图形.处理这些(相对罕见)情况的方法包括对数深度缓冲区和多遍渲染方法.

If the above is not enough, the solutions get more complex. There are scenarios where there is really geometry with a large range of depth that must be visible at the same time. Methods for dealing with these (relatively rare) cases include logarithmic depth buffers, and multi-pass rendering approaches.

请注意,我的回答纯粹是关于世界空间中原始多边形具有不同深度的情况.如果绘制深度完全相同的多边形(即共面多边形),则几乎总是会发生深度冲突,因此需要使用其他方法来避免这种情况.由于这看起来不像这里的情况,因此我特意不进行介绍.

Note that my answer is purely about the case where the original polygons in world space have different depth. If polygons with exactly the same depth (i.e. coplanar polygons) are drawn, depth fighting will almost always be the result, and this situation needs to be avoided with other methods. Since this doesn't look like the scenario here, I intentionally did not cover it.

这篇关于OpenGL-Java-渲染问题,多边形闪烁并消失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆