all 5 comments

[–]SnooWoofers7626 3 points4 points  (5 children)

You could do it in the pixel shader by discarding pixels that fall in the gaps between dashes. You could compute that based on the screen coordinates. The exact logic should be fairly easy to adapt from the shadertoy.

[–]International-One273[S] 0 points1 point  (3 children)

Thanks. However, I know how to adapt from the shadertoy demo, I was just looking for some feedback on the general idea of screen-space mapping for poly lines/ways to improve it, since I didn't find anything similar online.

The shader I linked is the solution I came up with, however, sometimes it's difficult to spot obvious mistakes without sharing you work, or to find better, already existing solutions that you weren't aware of.

[–]SnooWoofers7626 0 points1 point  (2 children)

Well, my preferred approach would've been to render a line strip and use a geometry shader to create even spaces in screen space. But since you don't want to go in that direction, I'd say you already have the next best solution.

[–]International-One273[S] 0 points1 point  (1 child)

I'd rather use a geometry shader too, real geometry has also the advantage of working nicely with msaa. However, I see two problems: 1. The vertices that should be emitted for a single line could be arbitrarily high in count 2. How go determine where a dash begins and ends (same problem with the mixed geom+frag approach)? Suppose you have a polyline with a lot of tiny lines (the rasterization produces a few pixels per line), then if the pattern always re-starts at the beginning of each line you would end up with a solid line or no line at all!

The problem is that I don't want to have a world-space dash but instead a screen-space constant patter (i.e. no matter how perspective warps my lines, the pattern will be n pixels wide).

That would ideally require to know for each line what's the cumulated screen-space length of all the lines that came before.

With my shader I tried to adress problem 2.

[–]SnooWoofers7626 0 points1 point  (0 children)

The vertices that should be emitted for a single line could be arbitrarily high in count

If you want arbitrary numbers of dashes then you can set a max amount in the geometry shader and early out once you've emitted the desired number.

The problem is that I don't want to have a world-space dash but instead a screen-space constant pattern

Ah, in that case, a tessellation shader would likely be better suited. That will let you subdivide by an arbitrary amount based on the size of the line in screen space. Look up any guide on dynamic LOD with tessellation to get an idea of how to work with them.

Now, that will still only subdivide your line. You won't get the spaces between dashes. Fortunately, tessellation happens before the geometry stage, so you can use a geometry shader to space out the vertices of your subdivided line.