【问题标题】:GL_LINES isn't drawn properly around GL_QUADS (possible z-fight?)GL_LINES 没有在 GL_QUADS 周围正确绘制(可能是 z-fight?)
【发布时间】:2018-08-01 14:53:25
【问题描述】:

我有三个基本的绘制曲面的函数,第一个是绘制曲面;

    def deflected_3d_surface(self, array):
        glBegin(GL_QUADS)
        for d in range(int(array.shape[0] / 2 - 1)):
            glColor4f(1, 1, 1, 1)
            glVertex3fv(array[2 * d + 2, :])
            glVertex3fv(array[2 * d, :])
            glVertex3fv(array[2 * d + 1, :])
            glVertex3fv(array[2 * d + 3, :])
        glEnd()

第二个绘制该表面的外边缘;

def deflected_3d_edges(self, array2):
    glBegin(GL_LINES)
    for i in range(array2.shape[0] - 1):
        glColor3fv((0, 0, 0))
        glVertex3fv(array2[i, :])
        glVertex3fv(array2[i + 1, :])
    glEnd()

第三个是在那个表面上画线; (注意线顶点和面顶点不一样)

def deflected_3d_inner_edges(self, x_array, y_array, z_array): 
   glBegin(GL_LINES)
    for i in range(x_array.shape[0]):
        glColor3fv((0, 0, 0))
        glVertex3fv([x_array[i, 0], y_array[i, 0], z_array[i, 0]])
        glVertex3fv([x_array[i, 1], y_array[i, 1], z_array[i, 1]])
        if x_array.shape[1] != 2:
            glVertex3fv([x_array[i, 1], y_array[i, 1], z_array[i, 1]])
            glVertex3fv([x_array[i, 2], y_array[i, 2], z_array[i, 2]])
    glEnd()

当我按以下顺序调用这些函数时;

`glWidget.deflected_3d_edges(self, self.tf1_edges_array)
 glWidget.deflected_3d_edges(self, self.tf2_edges_array)
 glWidget.deflected_3d_edges(self, self.bf1_edges_array)
 glWidget.deflected_3d_edges(self, self.bf2_edges_array)
 glWidget.deflected_3d_inner_edges(self, self.xbcr_, self.ybcr_, 
      self.zbcr_)
     glWidget.deflected_3d_inner_edges(self, self.xwcr_, self.ywcr_,
          self.zwcr_)
 glWidget.deflected_3d_inner_edges(self, self.xtcr_, self.ytcr_, 
      self.ztcr_)`

有什么办法可以修复出现在白色表面上的黑线吗?

【问题讨论】:

  • 似乎是一个“z-fight”案例。尝试对这些线坐标进行微小的增量,以便它们更接近(或更远)到相机。或者在渲染它们之前更改深度比较函数,
  • 解决了,但是当我旋转场景时,我现在看不到另一边的线条。
  • 设置Depth offset。在绘制整个几何图形之前执行glEnable( GL_POLYGON_OFFSET_FILL );glPolygonOffset( 1.0, 1.0 );。当然,您可以为GL_POLYGON_OFFSET_LINE istead 设置负深度偏移。
  • 这有帮助,但在某些表面上仍然存在 z-fight。
  • @Atlanta 的默认深度函数是GL_LESS,改用glDepthFunc(GL_LEQUAL)

标签: python opengl pyopengl


【解决方案1】:

当一个片段(将其视为一个像素)将被设置在帧缓冲区 FB 中(窗口的上一步)时,OpenGL 将其 Z 坐标与当前的 Z 坐标进行比较,以获得相同的 X、Y NDC 坐标( FB)。

默认情况下,如果传入的 Z 小于当前的 Z(它更靠近相机),则它获胜并替换 FB 中的旧颜色。这样一来,另一个片段后面的片段就会被丢弃。

当碎片具有相似的 Z 坐标时,尚不清楚谁领先。有时,由于数值浮点数不精确,最近的片段“丢失”并错误地被丢弃。这就是所谓的“z-fighting”。

如果你想看到一些东西,不管它在其他图元的前面或后面,你可以将glDepthFunc更改为GL_ALWAYS

所以:

  1. 绘制曲面
  2. 设置glDepthFunc(GL_ALWAYS)
  3. 画出你经常看到的对象
  4. glDepthFunc 恢复为正常的'GL_LESS`

【讨论】:

  • 谢谢。实际上,这解决了线条不渲染的问题,但它也导致表面表现得像透明。是否可以同时避免这种情况? example problem
  • @Atlanta's As Rabbid76 建议,使用glPolygonOffset。为了更好地控制,忘记固定管道,移动到 OpenGL >= 3.2 并在 片段着色器中进行校正。
  • 这有帮助,但在某些表面上仍然存在 z-fight。不幸的是,我对片段着色器没有任何经验。
  • @Atlanta's 如果您坚持使用 OGL
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-12
相关资源
最近更新 更多