PDA

View Full Version : Repeating texture on a line expanded with triangles



zhivchik
04-06-2017, 08:03 AM
I'm trying to determine an approach to put a repeating texture (lets say dash-dot-dot) on a thick line made of triangles. The challenge is that I do not have all the mesh vertices available to me at once. I am passing four adjacent vertices of a polyline to my geometry shader, using GL_LINE_STRIP_ADJACENCY, where I expand them into a triangular mesh to achieve the thickness effect that is available in legacy GL. I create one thick segment at a time using the two adjacent vectors to compute a miter. The texture pattern can span over several segments. The segments will vary in length. I can pass the distance of each polyline vertice from the origin to my geometry shader but what is the best way to relate that to the mesh coordinates? Do I have to pre-compute the texture map points on the CPU and pass them to the shaders or is there an easier/better approach?

GClements
04-06-2017, 09:59 AM
The simple approach is to make the horizontal texture coordinate proportional to the distance along the path from the endpoint, with the vertical coordinate one of two constants depending upon which side of the (thick) line it's on.

The main downside with that approach is that it can "kink" the texture mapping at the corners (vertices). A more advanced approach is to adjust the tessellation so that the boundary between the segments only passes through regions which correspond to either a space or the full-thickness interior of a dash, never to the boundary between a dash and a space.

zhivchik
04-06-2017, 11:00 AM
The simple approach is to make the horizontal texture coordinate proportional to the distance along the path from the endpoint, with the vertical coordinate one of two constants depending upon which side of the (thick) line it's on.

The main downside with that approach is that it can "kink" the texture mapping at the corners (vertices). A more advanced approach is to adjust the tessellation so that the boundary between the segments only passes through regions which correspond to either a space or the full-thickness interior of a dash, never to the boundary between a dash and a space.

I am not extremely concerned about the "kinking" of the texture. It might be even possible to map the texture to the part of the corner, so it is aligned with the corner of the next segment. With this approach wouldn't I also have to somehow track where the previous texture tile ended in the relation to the current segment? Maybe the remainder of the division of scaled distance along path by the length of texture tile? BTW I don't want the textures to scale with the line, I just want more dashes for a longer line. Since I'm fairly new to OpenGL I want to make sure I'm not missing a functionality or convention that would make it easier. So far it appears that lower level coding is in my cards.

zhivchik
04-06-2017, 11:14 AM
The simple approach is to make the horizontal texture coordinate proportional to the distance along the path from the endpoint, with the vertical coordinate one of two constants depending upon which side of the (thick) line it's on.

The main downside with that approach is that it can "kink" the texture mapping at the corners (vertices). A more advanced approach is to adjust the tessellation so that the boundary between the segments only passes through regions which correspond to either a space or the full-thickness interior of a dash, never to the boundary between a dash and a space.

I am not extremely concerned about the "kinking" of the texture. It might be even possible to map the texture to the part of the corner, so it is aligned with the corner of the next segment. With this approach wouldn't I also have to somehow track where the previous texture tile ended in the relation to the current segment? Maybe the remainder of the division of scaled distance along path by the length of texture tile? BTW I don't want the textures to scale with the line, I just want more dashes for a longer line. Since I'm fairly new to OpenGL I want to make sure I'm not missing a functionality or convention that would make it easier. So far it appears that lower level coding is in my cards.

arekkusu
04-06-2017, 11:55 AM
Do I have to pre-compute the texture map points on the CPU and pass them to the shaders or is there an easier/better approach?

Computing the stipple phase offset across line segments is a serialized problem; you need the length of segment N before you can draw segment N+1. If you're already computing per-point data on the CPU (i.e. flattening a curve) then you might as well compute screen-space distance and accumulate the length along the curve at the same time.

If you're computing all the per-point data on the GPU, and you want to also compute the accumulated length on the GPU, you can do that in separate setup passes (compute a parallel prefix sum). Then expand segments and read the per-segment accumulated length to set the texture coordinates in the final draw pass.



Since I'm fairly new to OpenGL I want to make sure I'm not missing a functionality or convention that would make it easier.

If you're comfortable with the built-in line stipple appearance, then the obvious functionality is glEnable(GL_LINE_STIPPLE), which can be accelerated in hardware (https://www.google.com/patents/US9501847) more efficiently than you can do yourself with reduction passes.

zhivchik
04-07-2017, 07:19 AM
If you're comfortable with the built-in line stipple appearance, then the obvious functionality is glEnable(GL_LINE_STIPPLE), which can be accelerated in hardware (https://www.google.com/patents/US9501847) more efficiently than you can do yourself with reduction passes.

I am not using any legacy functionality in my project so GL_LINE_STIPPLE is not an option.

zhivchik
04-07-2017, 07:32 AM
I came up with an easier alternative solution. Instead of using textures on my triangle mesh lines, I supplied them with solid color. I used the the scaled distances along path that I supplied with my vertices to discard fragments in the fragment shader using a sinusoidal. By combining different sinusoidals, I can create different stipple patterns. There is no "kinking" that I can notice and I can modify my stipples on the fly using uniforms. All scaling happens in the vertex shader so I'm not using the CPU.

arekkusu
04-07-2017, 09:52 AM
Sounds similar to this paper (http://jcgt.org/published/0002/02/08/).