Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Unexpected behavior of geometry shader using line adjacency input

Discussion in 'Shaders' started by warance, Jul 31, 2015.

  1. warance

    warance

    Joined:
    May 4, 2014
    Posts:
    11
    Hi,

    I am trying to write a simple shader to draw 3D line with thickness just to learn geometry shader in unity. However I am facing problem with the output from the shader when setting the input of the geometry shader to lineadj topology, which i suspect has something to do with the "weird" value of the third and fourth vertex taken in by the geometry shader.

    This is how i generate my mesh from a c# script:

    Code (CSharp):
    1.     public static GameObject DrawShaderLine(Vector3[] posCont, float thickness, Material mat)
    2.     {
    3.         GameObject line = CreateObject ("Line", mat);
    4.         line.GetComponent<Renderer>().material.SetFloat("_Thickness", thickness);
    5.  
    6.         int posContLen = posCont.Length;
    7.         int newVerticeLen = posContLen + 2;
    8.  
    9.         Vector3[] newVertices = new Vector3[newVerticeLen];
    10.  
    11.         newVertices[0] = posCont[0] + (posCont[0]-posCont[1]);
    12.  
    13.         for(int i =0; i < posContLen; ++i)
    14.         {
    15.             newVertices[i+1] = posCont[i];
    16.         }
    17.  
    18.         newVertices[newVerticeLen-1] = posCont[posContLen-1] + ( posCont[posContLen-1] - posCont[posContLen-2]);
    19.  
    20.  
    21.         List<int> newIndices = new List<int>();
    22.  
    23.         for(int i = 1; i< newVerticeLen-2; ++i)
    24.         {
    25.             newIndices.Add(i-1);
    26.             newIndices.Add(i);
    27.             newIndices.Add(i+1);
    28.             newIndices.Add(i+2);
    29.  
    30.  
    31.         }
    32. //        newIndices.Add(0);
    33. //        newIndices.Add(1);
    34. //        newIndices.Add(2);
    35. //        newIndices.Add(3);
    36.  
    37.         Mesh mesh = (line.GetComponent (typeof(MeshFilter)) as MeshFilter).mesh;
    38.         mesh.Clear ();
    39.         mesh.vertices = newVertices;
    40.         //mesh.triangles = newTriangles;
    41.         mesh.SetIndices(newIndices.ToArray(), MeshTopology.LineStripe, 0);
    42.         return line;
    43.     }

    And this is the GS that is running in the shader program

    Code (CSharp):
    1. v2g vert(appdata_base v)
    2.             {
    3.                 v2g OUT;
    4.                
    5.                 OUT.pos = v.vertex;
    6.                
    7.                 return OUT;
    8.             }
    9.                        
    10.             [maxvertexcount(2)]
    11.             void geom(lineadj v2g p[4], inout LineStream<g2f> triStream)
    12.             {
    13.                            
    14.                 float4x4 vp = mul(UNITY_MATRIX_MVP, _World2Object);
    15.                
    16.                 g2f OUT;
    17.                
    18.                 float4 pos0 = mul(vp, p[0].pos);
    19.                 float4 pos1 = mul(vp, p[1].pos);
    20.                 float4 pos2 = mul(vp, p[2].pos);
    21.                 float4 pos3 = mul(vp, p[3].pos);
    22.  
    23.                 OUT.pos = pos1;
    24.                 OUT.c = half4(1,0,0,1);  
    25.                 triStream.Append(OUT);
    26.                
    27.                 OUT.pos = pos2;
    28.                 OUT.c = half4(0,1,0,1);
    29.                 triStream.Append(OUT);
    30.                
    31.                 triStream.RestartStrip();
    32.            
    33.             }

    From my understanding, lineadj will take in 4 vertex with vertex[0] and vertex[3] being the adjacent vertexes. So by drawing vertex 1 and vertex 2 i am suppose to get my line drawn. However this is the output i get



    This input data vertex position is (-20,0,0) and (0,-20,0) which is marked by the center 2 squares. The top left and bottom right cube are the position of the adjacent vertex generated by the c# function. As you can see the line seem to be connecting to position (0,0,0) and the lines are flickering rapidly, which make me suspect that vertex in the GS is corrupted? Start of the line is colored red and the end of the line is colored green.

    If I edit the GS to output pos0 and pos1 instead of pos1 and pos2, i get this



    with no flickering lines.

    and if i plot pos2 and pos3, the result is way crazier(pos2 and pos 3 seems to be rubbish value).

    I have been trying to debug this for the whole day but with no progress, so I need some help here! Thanks in advance
     
  2. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    Unfortunately, this feature doesn't seem to be working in Unity. As far as I know, only the default triangle primitive type works, maybe even line and point. But the adjacency types are definitely not supported and the data for the extra vertices is garbage.
     
  3. warance

    warance

    Joined:
    May 4, 2014
    Posts:
    11
    Hi Dolkar,

    Thanks for the info. Guess i will have to make do with it for now.

    Question for dev: Is this feature going to get added into the future patches?