OpenGL:3D中厚而光滑/不折断的线条*

时间:2016-04-15 20:01:53

标签: opengl glsl openscenegraph

我有一个类似3D CAD的应用程序,我使用OpenGL包装器库(OpenSceneGraph)。对于应用程序,我正在尝试提出如何在3D中呈现粗细线条的最佳策略

厚而光滑我的意思是:

  • 线条粗细可以超过OpenGL最大线宽值(我的机器上似乎是10.f
  • 在编写折线时,我想避免看到“虚线”(见下面的示例图片)

OpenGL <code>LineStrip</code> looks broken, zoomed-in image

目前我使用GL_LINE_STRIP_ADJACENCY渲染我的折线。

我发现有许多关于如何在2D中渲染漂亮的线条和曲线的资源。最简单的方法是不需要太多思考就是将该行渲染为一组四边形(GL_QUAD_STRIP)。这个解决方案的好处是它可以同时解决我的两个问题。

作为一个例子,我还发现这个nice library可以实现广泛的线条和曲线外观。它使用三角形进行渲染。

注意:我不寻求像顶点着色或类似画笔的笔画那样的花哨效果,只是一个3D线段,它可以有很大的厚度,并且可以很好地与另一个线段连接他们之间的差距。

这些2D方法的问题是它们是2D。当我改变视点时,很明显我的线条几何形状不是线条,而是2D“条带”位于某些3D平面中。我希望它们看起来像3D线条。

在考虑问题时,我只能提出以下方法

  1. 将线渲染为一组2D四边形(三角形),然后使它们始终面向相机
  2. 使用像圆柱体这样的3D形状来表示线段
  3. 我不确定两种解决方案中的任何一种是否可行(我是OpenGL初学者)。我可能在场景中有数百甚至数千个折线。我也想知道是否有更好,更聪明的方法来解决这个问题?我对任何事情持开放态度,对最有效的方式感兴趣。谢谢。

    编辑:正如用户@rickyviking指出的那样,我没有明确说明我正在寻找2D外观(就像在任何类似CAD的应用程序中),这意味着:厚度线条不取决于相机距离它们的距离/附近。

    更新:感谢@rickyviking的回答,我选择了方向移动 - 几何着色器。我仍然没有完整的解决方案,但可能会在结果发布后发布最终更新和最少的代码。

4 个答案:

答案 0 :(得分:6)

我最终使用了几何着色器,如其中一个答案所示。主要思想是将每个线段转换为三角形条带,并确保它始终面向相机,厚度保持不变。

我还写了一篇关于实现细节的blog post。如果有人发现它有用,我将着色器代码放在one of my github repos上(该代码还提供了如何使用相同的技术绘制厚而光滑的贝塞尔曲线的示例)。

以下是一些结果屏幕截图(使用着色器绘制绿线,使用GL_LINE_STRIP_ADJACENCY绘制红色):

same thickness example

bigger thickness example

请注意红线的相邻线段与绿线相比的间隙。

两条贝塞尔曲线(全部使用着色器绘制):

Bezier curve examples

答案 1 :(得分:2)

首先,您需要自己澄清一下您之后的结果是否应该&#34;看&#34; 2D或3D。

当你提到气缸时,他们肯定会有一个3D效果&#34; (几何形状比靠近视点的几何形状更薄/更小),但这不是类似CAD的应用程序通常的样子。
我相信你是在2D外观结果之后,你的线条的宽度与它们与视点的距离无关。

使用库like the one you mention时,每次更改视点(可能是每个帧)时都应重新计算几何,以使它们始终面向屏幕平面。

另一种更好的表现方法是使用&#34;实线框&#34;技术,这里是an implementation from NVidia,它使用几何着色器(你可以找到几个关于如何在OpenSceneGraph中使用它们的例子)。
其他类似技术如下所示:https://forum.libcinder.org/topic/smooth-thick-lines-using-geometry-shader

答案 2 :(得分:1)

我不太了解它,但关于NVidia's "path rendering" SDK的许多有趣的事情之一(面对它只是另一个你正在讨论的漂亮2D库中的一个) )它实际上是在与3D互操作方面付出了一些努力。参见&#34; Eureka:3D路径渲染!&#34; this whitepaper中的部分。

曾经有人说过它会成为一个标准的(非特定于供应商的)OpenGL扩展,但我不确定它是否曾经发生过。

答案 3 :(得分:0)

之前我曾使用过气缸,但​​这是一款需要实际尺寸,一行不同尺寸甚至颜色变化的应用。