鉴于任意3D网格,我正在寻找一种能够实时执行隐藏线删除的算法。我在OpenGL环境中工作,这意味着我们可以利用Z-Buffer。
我想该算法应该包含以下两个问题的解决方案:
1)定义哪些是“硬边缘”,以便稍后使用常规OpenGL线绘制它们。这些“硬边缘”应该对应于两个相应面之间的角度高于某个阈值的边缘。
为简单起见,让我们声明保证每条边不超过2个面。
每个网格应该进行一次“硬边”的计算,即它与视点无关。
2)根据当前视点定义网格轮廓的轮廓。最终,这部分可以使用经典的OpenGL技术(涉及多边形偏移或模板缓冲)来完成,但最好使用常规OpenGL线绘制轮廓,以保持统一的外观和放大。感觉所有的线条。
对于那部分,我不确定轮廓的顶点是否都应该通过网格顶点。在任何情况下,对于像立方体这样的网格,其中不需要轮廓(因为它足以仅绘制“硬边缘”)_算法应该足够智能以避免两次绘制“相似的线”。
答案 0 :(得分:4)
这里有几件事情要发生。首先,你想绘制网格线,然后你想绘制一个轮廓。这是使这项工作的通用程序,
仅通过清除color mask将(使用三角形)网格绘制到深度缓冲区。
重新打开颜色遮罩,切换front face,然后将网格重新缩放/偏移一些小百分比。翻转正面使您只能看到偏移网格的内部,该网格会被先前绘制的网格的深度缓冲区剪切。如果你这样做,它应该给你一个整洁的轮廓。以下是此技术的示例:http://www.codeproject.com/KB/openGL/Outline_Mode.aspx
最后,在现有网格和外壳上绘制网格边缘(同时保持深度缓冲区与前两个操作完好无损)。
结果是,您现在将绘制网格的所有边缘,并且具有漂亮的轮廓!
编辑:第二次重新阅读你的帖子后,听起来你不想绘制所有边缘,只有那些出现在曲率足够高的边界的边缘。因此,要执行此操作,您可以执行以下操作之一:
预处理网格边缘,并剔除连接几乎共面面对的所有边。通过比较法线的点积可以很容易地检查。如果它足够接近1,则从渲染集中丢弃该边缘。
更一般地说,您还可以在屏幕空间中近似网格的曲率。这样做是计算所谓的屏幕空间环境遮挡的反过来。 (此处列出了此技术的另一个巧妙应用:http://zigguratvertigo.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/)一旦从深度缓冲区计算了对象的曲率,就可以通过仅绘制出现在像素上的线段来过滤掉线条曲率。
答案 1 :(得分:1)
这就是你要找的东西吗?
诀窍是去除钝的边缘。棘手的部分是使阈值正确,每个对象可能不同。
This article explains more about the algorithm一般来说,它是最快的to implement the effect using a pixel shader