# Geometry shader with MeshTopology.LineStrip ?

Discussion in 'Shaders' started by Avol, May 26, 2019.

1. ### Avol

Joined:
May 27, 2016
Posts:
46
Is it possible to use something like a geometry shader to draw multiple lines from a single line strip mesh? Geometry shader works with triangles and MeshTopology.LineStrip does not have tris.
Thinking of a way to save memory when drawing hundreds of lines with small noise factor along 1 line.

2. ### bgolus

Joined:
Dec 7, 2012
Posts:
7,894
Geomerty shaders have an input and output type, and they don't have to match. If your mesh is using a line topology, then use the line input type.

However Unity doesn't have adjacency support, so you'd have to store the next vertex position in the vertex data. You might be better off using triangle topology still, with each triangle being the two points of the line plus the next vertex.

Avol likes this.
3. ### Avol

Joined:
May 27, 2016
Posts:
46
I came to such a solution:

Code (CSharp):
1.
2.              void ComputeQuadPoints(float4 p1, float4 p2,
3.                                     out float4 o1, out float4 o2, out float4 o3, out float4 o4)
4.              {
5.                 float2 dir      = normalize(p2.xy - p1.xy);
6.                 float2 normal   = float2(-dir.y, dir.x);
7.                 float4 offset1  = float4(normal * 0.05f / 2.0f, 0, 0);
8.                 float4 offset2  = float4(normal * 0.05f / 2.0f, 0, 0);
9.                 o1 = p1 + offset1;
10.                 o2 = p1 - offset1;
11.
12.                 o3 = p2 + offset2;
13.                 o4 = p2 - offset2;
14.              }
15.
16.              [maxvertexcount(100)]
17.              void geom(line input p, inout TriangleStream<input> triStream)
18.              {
19.                 input g;
20.                 uint id = p.pos.w;
21.
23.                 float4 p1 = UnityObjectToClipPos(float4(p.pos.xyz, 1));
24.                 float4 p2 = UnityObjectToClipPos(float4(p.pos.xyz, 1));
25.                 float4 o1, o2, o3, o4 = 0;
26.                 ComputeQuadPoints(p1, p2, o1, o2, o3, o4);
27.                 // get prev line quad
28.                 bool prevExists = false;
29.                 float4 oP1 = 0; float4 oP2 = 0; float4 oP3 = 0; float4 oP4 = 0;
30.                 if (id > 0)
31.                 {
32.                     float4 p1 = UnityObjectToClipPos(float4(_Points[id - 2].pos0.xyz, 1));
33.                     float4 p2 = UnityObjectToClipPos(float4(_Points[id - 1].pos0.xyz, 1));
34.                     ComputeQuadPoints(p1, p2, oP1, oP2, oP3, oP4);
35.                     prevExists = true;
36.                 }
37.
38.                 // draw strands
39.                 for (int x = 0; x < 5; x++)
40.                 {
41.                     for (int y = 0; y < 5; y++)
42.                     {
43.                         float   rndX    = nrand(float2(x, y));
44.                         float   rndY    = nrand(float2(y, -x));
45.                         float4  noise   = float4(rndX, rndY, 0, 0);
46.
47.                         if (!prevExists)
48.                         {
49.                             g.pos    = o1 + noise;
50.                             g.pos    = o2 + noise;
51.                         }
52.                         else
53.                         {
54.                             g.pos    = oP3 + noise;
55.                             g.pos    = oP4 + noise;
56.                         }
57.
58.
59.                         g.pos    = o3 + noise;
60.                         g.pos    = o4 + noise;
61.
62.                         triStream.Append(g);
63.                         triStream.Append(g);
64.                         triStream.Append(g);
65.                         triStream.Append(g);
66.                     }
67.                 }
68.             }

4. ### Hyp-X

Joined:
Jun 24, 2015
Posts:
206
Does your solution works with DirectX12 ?
I have a similar shader that works with DirectX11 but not with 12
I get:
``d3d12: the given primitive topology does not match the topology expected by the geometry shader.``
but I suspect it's a Unity bug (2019.2.7f2)

5. ### Avol

Joined:
May 27, 2016
Posts:
46
Yes, though I tweaked it quite a bit since this post. Are you using MeshTopology.Lines instead of MeshTopology.LineStrip?