OpenGL : thick and smooth/non-broken lines *in 3D*

那年仲夏 提交于 2020-02-26 10:34:58

问题


I have a 3D CAD-like application for which I use OpenGL wrapper library (OpenSceneGraph). For the application I am trying to come up with the best strategy on how to render thick and smooth lines in 3D.

By thick and smooth I mean:

  • line thickness can be more than OpenGL maximum linewidth value (it seems to be 10.f on my machine)
  • when composing polylines I want to avoid the look of "broken lines" (see example image below)

At the moment I render my polylines by using GL_LINE_STRIP_ADJACENCY.

I found there are many different resources on how to render nice looking lines and curves in 2D. The simplest approach that does not require much thinking is to render the line as a set of quads (GL_QUAD_STRIP). The good thing about this solution is that it solves both of my problems at the same time.

As an example, I also found this nice library that allows to achieve wide range of line and curve looks. It uses triangles for rendering.

Note: I do not seek for fancy effects like per-vertex coloring or brush-like strokes, just a 3D line segment that can have large thickness and that connects well with another line segment without any gaps between them.

The problem with those 2D approaches is that they are 2D. When I change the view point, it is obvious my line geometries are not lines but rather 2D "ribbons" lying in certain 3D planes. And I want them to look like 3D lines.

When thinking about the problem, I could only come up the the following approaches:

  1. Render line as a set of 2D quads (triangles) and then make them to always face the camera
  2. Use some 3D shape like cylinder to represent a line segment

I am not sure how feasible any of the two solutions are (I am beginner in OpenGL). I might have hundreds or even thousands of polylines on the scene. I am also wondering if there is a better, smarter way to approach the problem? I am open to anything and interested in the most efficient way. Thank you.

EDIT: as pointed by user @rickyviking, I didn't clarify explicitly that I am going after a 2D look (like in any CAD-like app) which would mean: the thickness of the lines does not depend on how far/near the camera is located from them.

UPDATE: thanks for answer of @rickyviking, I chose the direction to move with - geometry shaders. I still do not have a complete solution, but might post a final update and minimal code when the result is achieved, here.


回答1:


First of all you need clarify yourself whether the result you're after should "look" 2D or 3D.

When you mention cylinders, they will certainly have a "3D effect" (geometries farther away thinner/smaller than geometries closer to the viewpoint), but that is not what CAD-like applications normally looks like.
I believe you're after a 2D looking result, where the width of your lines is independent from their distance from viewpoint.

When using a library like the one you mention, you should recompute the geometries every time you change your viewpoint (possibly every frame) to have them always face the screen plane.

An alternative and better performing approach would be to use the "solid wireframe" technique, here is an implementation from NVidia, which uses geometry shaders (you can find several examples on how to use them in OpenSceneGraph).
Other similar techniques are shown here: https://forum.libcinder.org/topic/smooth-thick-lines-using-geometry-shader




回答2:


I ended up using geometry shader as was suggested by one of the answers. The main idea was to convert every line segment into a triangular strip and to make sure that it always faces the camera and thickness remains the same.

I also wrote a blog post about the implementation details. If someone finds it useful, I placed the shader codes on one of my github repos (the code also provides example on how to draw thick and smooth Bezier curves using the same technique).

Here are some result screenshots (green lines are drawn using the shaders, red are by using GL_LINE_STRIP_ADJACENCY):

Note the gaps between the adjacent line segments of the red lines compared to the green ones.

Two Bezier curves (all drawn using the shaders):




回答3:


I don't know too much about it but one of the many interesting things about NVidia's "path rendering" SDK (which was on the face of it just another one of those nice 2D libraries you're talking about) was that it actually put a bit of effort into interoperating with 3D. See the "Eureka: 3D Path Rendering!" section in this whitepaper.

There used to be talk of it becoming a standard (non-vendor-specific) OpenGL extension but I'm not sure it ever happened.




回答4:


I've used cylinders before, but that was an application that needed actual real-world sizes, varying sizes in one line and even color changing.



来源:https://stackoverflow.com/questions/36655888/opengl-thick-and-smooth-non-broken-lines-in-3d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!