沿着不相交的三角形边缘进行Z战斗

时间:2014-03-02 04:59:57

标签: opengl opentk depth-buffer

我有一个OpenGL程序,它表现出不寻常的z战斗,并且因此而失败。似乎大多数战斗都是沿着三角形的边缘开始的。

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

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

顶点和片段着色器的制作尽可能简单。

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

我已将OpenGL FAQ列出的所有四项内容列为深度缓冲的要求。

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

还有其他可能导致这种z战斗的原因吗?

z-fighting Not overlapping

顶点矩阵的生成如下:

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卡上。经过英特尔测试,问题没有出现。

1 个答案:

答案 0 :(得分:1)

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

建议:

  1. 检查GL.GetString(StringName.Renderer) “Microsoft GDI渲染器”,因为这表示软件加速。
  2. 尝试请求24位深度缓冲区,而不是32位缓冲区,因为后者不受GPU支持。
  3. 通过Context.GraphicsMode.Depth仔细检查深度缓冲位。默认值为16bits。
  4. 请求32位时会发生什么情况取决于您使用的OpenTK版本。对于不支持的模式(如32位深度缓冲区),OpenTK 1.0将回退到软件加速。 OpenTK 1.1将更加努力地为您提供匹配的GraphicsMode,并且只会作为最后的手段回归软件加速。