地形在水中闪烁 |深度缓冲精度问题?

Terrain flickers through water | Depth buffer precision issue?

我的地形中的水有问题,目前它只是一个透明蓝色的四边形。

近看是这样的:

如您所见,它很简单 - 代表水的扁平透明四边形。

但是,当我离得更远时,会发生这种情况:

对于那些看不到 GIF 或需要 external link(或无法理解发生了什么)的人来说,水域周围的地形会出现故障。如果你离水足够近,你会看到地形出现故障 above/below 它。

这是我准备 3D 视图的代码:

static void ready3D()
{
    glViewport(0, 0, Display.getWidth(),Display.getHeight());
    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();
    GLU.gluPerspective(45, (float) Display.getWidth()/Display.getHeight(), 50f, 500f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);
}

有谁知道问题出在哪里,以及如何提高深度缓冲区的精度(假设深度缓冲区是问题所在)?

很难从 GIF 中分辨出来,但我收集到的信息是您遇到的是 Z-Fighting

有几种解决方案往往对处理 Z-Fighting 最有效:

  • 提高 Z 缓冲区的分辨率。
  • 调整Water & Land的相对位置,将它们进一步分开,从而减少两个几何体像这样碰撞的几率
  • 使用模板缓冲区确保正确绘制对象。

我也见过在处理某些对象时尝试禁用深度测试的解决方案,但这些解决方案几乎从来都不是通用解决方案。

增加深度缓冲区不会有太大帮助,因为拥有一个开放的世界会导致从 zNear 到 zFar 的距离很大,这会映射到您的深度缓冲区。一个常见的技巧是实现 logarithmic depth buffer. This gives you an ability to accent where do you need details but in current situation this need changes with altitude of your vehicle+camera system. So logarithmic buffer is not a solution and increasing "linear" buffer wouldn't affect a lot. I recommend to read this and this 关于深度缓冲区的精彩文章。

第二点是你的景观似乎是程序生成的。如果是这样的话,顶点可能会在非常接近水面高度的地方生成。在这个浮点比较中获胜 war 仅靠深度缓冲区操作(如果可能的话)并不简单。

第三点是,通常您不需要额外的运行时作业,这就是模板缓冲区使用在这里存在问题的原因(正如 JPhi1618 注意到的那样)。

因此,如果您有机会修改景观生成算法,从我的角度来看,这是值得的。再次来自 JPhi1618 话:

if Y is less than the level of the water even a little bit, make it way less than the water.