【问题标题】:Z-fighting along non-intersecting triangle edges沿不相交的三角形边缘进行 Z-fighting
【发布时间】:2014-03-02 04:59:57
【问题描述】:

我有一个 OpenGL 程序正在演示不寻常的 z-fighting 并且我迷失了这个原因。看起来大部分的战斗startx沿着三角形的边缘。

简化测试用例中的两个对象不相交,如下图。我确保 z-near 和 z-far 值是合理的(分别为 1 和 100)。这两个物体都在距离原点大约 2 个单位的范围内,在所示图像中,相机距离大约 10 个单位。

除了启用了深度测试之外,没有对 OpenGL 的默认深度设置进行任何更改。

顶点和片段着色器已尽可能简单。

这是使用 OpenTK。我已经尝试使用 32 位深度缓冲区显式创建窗口,但这也没有效果。

我已经了解了OpenGL FAQ 列出的深度缓冲要求的所有四件事。

关闭深度测试消除了战斗,使对象按绘图顺序重叠。程序中没有使用剔除或模板。

这种z-fighting还有其他可能的原因吗?

顶点矩阵的产生方式如下:

Matrix4 transform_matrix;
Matrix4.CreatePerspectiveFieldOfView((float) (45 * Math.PI / 180), aspect_ratio, 1, 100, out transform_matrix);
transform_matrix = Matrix4.Mult(transform_matrix, CameraMatrix);

CameraMatrix 就是这个方法的结果:

public void TransformMatrix(out Matrix4 m)
{
    var t = Matrix4.Identity;
    t.Column3 = new Vector4(Offset);

    var rx = Matrix4.Identity;
    var sine_x = (float) Math.Sin(-RotationX * Math.PI / 180);
    var cos_x = (float) Math.Cos(-RotationX * Math.PI / 180);
    rx.Row1 = new Vector4(0, cos_x, -sine_x, 0);
    rx.Row2 = new Vector4(0, sine_x, cos_x, 0);

    var ry = Matrix4.Identity;
    var sine_y = (float) Math.Sin(-RotationY * Math.PI / 180);
    var cos_y = (float) Math.Cos(-RotationY * Math.PI / 180);
    ry.Row0 = new Vector4(cos_y, 0, sine_y, 0);
    ry.Row2 = new Vector4(-sine_y, 0, cos_y, 0);

    var n = Matrix4.Mult(rx, t);
    n = Matrix4.Mult(ry, n);

    m = n;
}

更新

这只发生在 NVIDIA 卡上。经 Intel 测试,未出现问题。

【问题讨论】:

  • 在我看来不像是 Z 战。尝试调试您的投影矩阵。

标签: opengl opentk depth-buffer


【解决方案1】:

这看起来不像是 z-fighting。这是一个疯狂的猜测,但是您的程序实际上是否使用了硬件加速?众所周知,微软的软件渲染器会产生这样的损坏。

建议:

  1. 检查GL.GetString(StringName.Renderer) 是否不是“Microsoft GDI 渲染器”,因为这表明软件加速。
  2. 尝试请求 24 位深度缓冲区,而不是 32 位缓冲区,因为 GPU 不支持后者。
  3. 通过Context.GraphicsMode.Depth 仔细检查您的深度缓冲区位。默认为 16 位。

当您请求 32 位时会发生什么取决于您使用的 OpenTK 版本。 OpenTK 1.0 将回退到不受支持的模式(如 32 位深度缓冲区)的软件加速。 OpenTK 1.1 将更加努力地为您提供匹配的GraphicsMode,并且只会在不得已的情况下使用软件加速。

【讨论】:

  • 32 位深度缓冲区受 GPU 支持。但是,Windows 上的许多 ICD 不会为具有 32 位深度缓冲区的默认帧缓冲区公开像素格式。换句话说,您通常必须使用 FBO 才能访问 32 位深度格式。
  • 肯定不是第一个,因为我在 Linux 上测试它。渲染器是GeForce GTX 560/PCIe/SSE2。深度默认为 24​​ 位。
  • 这看起来很奇怪。您可以在某处上传测试项目吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 2017-06-30
相关资源
最近更新 更多