opengl - 3D网格的隐藏线去除算法?

标签 opengl graphics geometry

给定一个任意的 3D 网格,我正在寻找一种可以实时执行隐藏线去除的算法。我在 OpenGL 的上下文中工作,这意味着我们可以利用 Z-Buffer。

我猜算法应该包括以下两个问题的解决方案:

1) 定义哪些是“硬边”,以便稍后使用常规 OpenGL 线绘制它们。这些“硬边”应该对应于 2 个对应面之间的角度高于某个阈值的边。

为简单起见,让我们声明保证每条边定义的面不超过 2 个。

“硬边”的计算应该对每个网格进行一次,即它与视点无关。

2) 根据当前视点定义网格轮廓的轮廓。最终,这部分可以使用经典的 OpenGL 技术(包括多边形偏移或模板缓冲区)来完成,但最好使用常规 OpenGL 线条绘制轮廓,以保持所有线条的统一外观和感觉。

对于那部分,我不确定轮廓的顶点是否都应该通过网格顶点。在任何情况下,对于像立方体这样的网格 _ 不需要轮廓(因为只绘制“硬边”就足够了)_ 算法应该足够聪明,以避免绘制两次“相似线”。 .

最佳答案

这里有几件事情正在发生。首先,您要绘制网格线,其次您要绘制轮廓。这是使这项工作的通用程序,

  • 仅通过清除 color mask 将(使用三角形)网格绘制到深度缓冲区.
  • 重新打开颜色 mask ,切换 front face ,并将您的网格重新缩放/偏移一些小百分比。翻转正面使您只能看到偏移网格的内部,该内部被先前绘制的网格的深度缓冲区剪裁。如果你做对了,它应该会给你一个整洁的轮廓。以下是此技术的示例:http://www.codeproject.com/KB/openGL/Outline_Mode.aspx
  • 最后,在现有的网格和 shell 上绘制网格的边缘(同时保持前两个操作中的深度缓冲区不变)。

  • 结果是您现在将绘制网格的所有边缘,以及漂亮的轮廓!

    编辑:第二次重读您的帖子后,听起来您不想绘制所有边缘,只绘制那些出现在具有足够高曲率的边界处的边缘。因此,为此,您可以执行以下操作之一:
  • 预处理网格的边缘,并剔除连接成对几乎共面的面的所有边缘。这很容易通过比较它们的法线的点积来检查。如果它足够接近 1,则从渲染集中丢弃该边。
  • 更一般地,您还可以在屏幕空间中近似网格的曲率。这样做与计算所谓的屏幕空间环境遮挡相反。 (此处列出了此技术的另一个巧妙应用: http://zigguratvertigo.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/ )一旦您从深度缓冲区计算出对象的曲率,您就可以通过仅绘制出现在具有足够高曲率的像素上的线条片段来过滤掉线条。
  • 关于opengl - 3D网格的隐藏线去除算法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6480574/

    相关文章:

    android - 如何在 Android 中创建可调整大小的交叉影线绘图

    c++ - Qt 如何在幕后共享 OpenGL 上下文?

    opengl - 使用 VBO 的最佳方式

    windows - 通过 WinAPI 确定英特尔高清显卡版本

    matlab - 给定已知坐标的 N 个点的距离,确定 3D 空间中点的位置

    algorithm - 线交点

    r - 使用 ggplot2 绘制圆形密度图

    c - 帧速率随窗口大小变化

    c++ - 如何基于许多不同的整数创建多种颜色

    graphics - 如何在 C++ 中绘制用于光线追踪的像素?