0

After looking at some programs for 2d modeling, I noticed that all primitives are drawn as segments (see attached picture). For example, why is the circle drawn as a polygon? It seems to me that it is much easier to create a shader that will draw a circle, regardless of the magnification (scaling)?

It is also interesting, These segments are drawn each separately or as one draw-call with a special shader for each shape?

What is the main reason that the developers chose this path? What they are trying to achieve?

example

genpfault
  • 51,148
  • 11
  • 85
  • 139
newWeb
  • 11
  • 2
  • 1
    Rendering a bunch of lines is usually way faster than rendering a quad and rendering a pixel-perfect circle in a shader. In addition, your technique would be hard to implement without aliasing when shown in full 3D. – BDL Feb 16 '21 at 08:41
  • @BDL it might be not as bad as you think see my [GLSL cubics](https://stackoverflow.com/a/60113617/2521214) however You're right lines are faster... But I think much more important is that the CAD SW is here much longer than shaders and often runs on custom gfx dedicated to CAD (I think they have different architecture too) so adding shaders to CADs might be too expensive or even not safe. Also this might be just a poorly ported legacy code as any decent CAD sets the number of segments in respect to zoom,detail and size of rendered primitive. The image looks like fixed number of segments. – Spektre Feb 16 '21 at 09:34

1 Answers1

0

3D graphics API support only triangles, dots and line segments - there is no built-in rendering primitives for drawing a circle or something like this. Therefore, the first two reasons for drawing all type of curves as a polyline are uniformity (you can render ANY type of curve as a set of line segments) and performance (line segments is the only native type supported by GPU). Drawing primitives of the same type using the same universal GLSL program allows rendering of many curves at once and reducing overall number of draw calls in optimized engine.

Moreover, you don't actually need a special GLSL program to avoid rough tessellation - just split your curve into more segments to make it appear smooth on the screen. You will have to balance between performance and quality, though - ideally, tessellation level should change dynamically basing on a zoom level and applied only to figures visible on the screen. This is not something trivial to implement, but it is much more straightforward when applied to 2D drawings than to 3D.

GLSL programs allow implementing various tricks, but rendering a fixed-width curve would require using a Tessellation Shader (or at least Geometry Shader), which WebGL doesn't support, or applying some dirty tricks! So I wouldn't say that drawing a thin circle of reliable quality via GLSL program will be that simple.

It is possible, though, rendering simple shapes like filled circle using just a Fragment Shader by drawing a rectangle and discarding fragments outside of the circle computed by circle equation. But that would be just a circle, a single solid circle, while there are a lot of other figures and combinations of them! Hence, again - uniformity and simplicity.

Indeed, there are applications implementing special GLSL programs for a limited set of commonly used figures, but these require a lot of development.

gkv311
  • 2,612
  • 1
  • 10
  • 11
  • fixed (even variable) width curve rendering does not require tesselation shaders at all. Geometry shader is sufficient see my [GLSL cubic](https://stackoverflow.com/a/60113617/2521214)... However I do not code in WebGL so I do not know if geometry shaders are implemented there so if not your point still holds – Spektre Feb 16 '21 at 09:46
  • @Spektre, Geometry Shaders can, but are not supposed to do tessellation job - they are very inefficient for this. Anyway, WebGL doesn't support any of them (WebGL 2.0 corresponds to OpenGL ES 3.0), hence I didn't mentioned Geometry Shaders. – gkv311 Feb 16 '21 at 11:03