Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Vectrosity - Fast and Easy Line Drawing

Discussion in 'Assets and Asset Store' started by Eric5h5, Sep 26, 2014.

  1. nikorenos

    nikorenos

    Joined:
    Jun 12, 2017
    Posts:
    28
    Hello, how can I animate line which I created? I can see there is a PartialLine animated in demo scene with script attached to camera, but what I need to do to animate my specific line?
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It depends on what you mean by "animate." What do you want to do?

    --Eric
     
  3. nikorenos

    nikorenos

    Joined:
    Jun 12, 2017
    Posts:
    28
    Draw the line. And can I attach any object to the beginning of the line?
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Change the line's drawEnd or drawStart values over time. It doesn't matter what the script is attached to; you use a reference to the line you created, like the AnimatePartialLine script does. You can't really attach objects to lines, but you could maybe use end caps instead. Otherwise you can just put the object at the desired coordinates yourself.

    --Eric
     
  5. nikorenos

    nikorenos

    Joined:
    Jun 12, 2017
    Posts:
    28
    But I don't know how to make reference in scrpit to line I created. It doesn't work as gameobject.
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The AnimatePartialLine script does exactly that. It creates a VectorLine, and uses the reference to the VectorLine to animate it.

    --Eric
     
  7. nikorenos

    nikorenos

    Joined:
    Jun 12, 2017
    Posts:
    28
    When I attach this script into my created line it still animates line from script not mine.
     
  8. nikorenos

    nikorenos

    Joined:
    Jun 12, 2017
    Posts:
    28
    Is it possible to animate line without creating line with script?
     
  9. heinzmueller

    heinzmueller

    Joined:
    Nov 30, 2017
    Posts:
    2
    Dear community,

    I'm trying to use the 'free anti-aliasing opportunity' vectrosity offers as described in the documentation linked below for 3D lines.
    Therefore, I'm using the material 'Unlit/Transparent' with the texture 'ThinLine' with bilinear filtering as explained in the documentation.

    The lines' textures I obtain seem to have a kind of tilted orientation so the lines appear dashed as shown in the image.

    Does anybody have a clue what I'm doing wrong?


    Documentation: https://starscenesoftware.com/files_vectrosity/Vectrosity5 Coding.pdf ,page 10

    Best regards,

    Heinz
     

    Attached Files:

  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Looks like the lines need to be thicker.

    --Eric
     
  11. drHogan

    drHogan

    Joined:
    Sep 26, 2012
    Posts:
    201
    Hello @Eric5h5

    I've been using and loving vectrosity for quite a while, I now have a bit of a problem with drawcalls. I was planning to use it to draw the province borders of our game, as shown in the picture


    I generate them through this code

    Code (CSharp):
    1. VectorLine lineDrawing = new VectorLine("Spline", new List<Vector3>(450 + 1), RandomTexture(), 5.0f, LineType.Continuous);
    2.             lineDrawing.joins = Joins.Fill;
    3.             lineDrawing.MakeSpline(points.ToArray(), 450, false);
    4.             lineDrawing.continuousTexture = true;
    5.             lineDrawing.material = lineMaterial;
    6.             lineDrawing.layer = 15;
    7.             lineDrawing.rectTransform.localPosition = new Vector3(0f, 0f, -2f);
    8.             lineDrawing.Draw3DAuto();
    The material settings are these, and the three different "hand-drawn" textures used are all into an atlas.



    Due to the way I need to display them dynamically upon exploring the map, they are drawn in segments, each being the border between 2 provinces (without duplicates).
    My problem are drawcalls through the roof. Each segment is 2 drawcalls, and despite being all on the same depth buffer position, they don't batch anyhow.
    Am I doing smth wrong or Splines in 3D don't batch? If not any of these, any suggestion on what I could do to minimize the drawcalls (maybe some way of merging the lines, etc..)

    Thanks in advance,
    Cheers,
    H
     
  12. heinzmueller

    heinzmueller

    Joined:
    Nov 30, 2017
    Posts:
    2

    Hi Eric,

    thanks for your answer, it worked perfectly well. I have one more question:

    Do you think writing my own shader for anti-aliasing purposes instead of using the texture might yield a significant improvement of FPS?

    Best regards,

    Heinz
     
  13. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    From the screenshot it doesn't look like there would be more than a couple dozen segments, which should be a non-issue. Dynamic batching has severe limitations on the number of vertex attributes that you can use, otherwise the time for batching exceeds the time for draw calls, and it would be pointless. (Batching might be pointless anyway on newer APIs like Vulkan and Metal, though I haven't looked into that.) However there doesn't seem to be a reason to use the standard shader, so a simpler unlit shader would reduce the draw calls to one per segment. Other than that, you could make a single VectorLine and turn segments on and off manually. The spline functions have optional indexes that you can use to put splines into any point in the list; e.g. the Curve demo. After that, turning segments on and off could be accomplished just by making the appropriate points in the list transparent or solid (requires a transparent shader of course).

    No, bilinear filtering is essentially "free" and any custom AA shader will be far slower.

    --Eric
     
  14. drHogan

    drHogan

    Joined:
    Sep 26, 2012
    Posts:
    201
    Hi Eric, thanks for the hints. I might have solved the problem.

    Actually the segments are 67 when the whole map is revelated, so 134 drawcall were indeed a problem, and i had some issues in using normal transparent shaders (i have hand-written like textures on the lines, that need alpha to work)

    The batching was broken by the splines, probably too many points and it failed, i managed to approximate with continuous lines, so all together it's 5 drawcalls, that it's totally acceptable. And the issues with transparency came from the fact that the sprites of the map had an order in layer greater than zero and that took them on top of the lines mesh renderers.

    Cheers
     
  15. philipmac

    philipmac

    Joined:
    Jun 24, 2017
    Posts:
    1
    Hi Eric,

    First off, thank you - vectrosity is awesome.

    I use vectrosity to draw realtime waveforms in VR, updating points in place every frame and calling Draw3D.

    I upgraded to 2017.2.0f3 and noticed a sharp dip in line drawing performance, 30 to 40%. I rolled back to 2017.1.2f1 and all goes back to normal.

    This happens both in editor and in a build. I'm on Windows 10 + 1060. I haven't been able to find any issue like this on the unity issue tracker.

    Attached is a sample project to reproduce it (you'll need to import vectrosity). In this sample on a release build I see Draw3D taking approx 1.3ms on 2017.1.2f1 and 1.9ms on 2017.2.0f3.

    Any ideas?

    Thanks
     

    Attached Files:

  16. PhilippCh

    PhilippCh

    Joined:
    Jun 14, 2013
    Posts:
    19
    Hi there!

    I'm experiencing some issues setting a line color during runtime.

    Code (CSharp):
    1.         public Color Color {
    2.             get { return color; }
    3.             set {
    4.                 color = value;
    5.  
    6.                 if (line == null) {
    7.                     return;
    8.                 }
    9.  
    10.                 line.color = color;
    11.             }
    12.         }
    13.  
    14.         private void CreateLine() {
    15.             var linePoints = new List<Vector3>(50);
    16.            
    17.             controlPoints = GetSphereArc(from, to, Vector3.zero, SphereRadius + Height);
    18.             lineObject = new GameObject("line");
    19.             line = new VectorLine("arc_line", linePoints, 2f, LineType.Continuous) {
    20.                 layer = 22, // TODO: Make this dynamic!
    21.                 color = Color
    22.             };
    23.  
    24.             VectorLine.SetCamera3D(RenderCamera);
    25.             line.MakeSpline(controlPoints.ToArray());
    26.             lineObject.transform.SetParent(transform, false);
    27.  
    28.             VectorManager.ObjectSetup(lineObject, line, Vectrosity.Visibility.Always, Brightness.None, false);
    29.         }
    I'm not able to set the color either during CreateLine or dynamically via the property I created. Is there anything I need to do besides setting line.color?

    Cheers
    Philipp
     
  17. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Vectrosity uses the exact same code for different versions of 2017, so any Unity regressions should be reported as a bug to Unity. It's fine to include Vectrosity when doing so. Unfortunately there's nothing I can do on my end about Unity performance issues. If it was Draw I might assume they were doing some weirdness with canvases, but Draw3D is just a standard mesh.

    I tested that and it works fine, though I modified "color = Color" to be "color = myColor", with myColor declared appropriately. I'd recommend not using variable names that are the same as Unity classes.

    --Eric
     
    philipmac likes this.
  18. PhilippCh

    PhilippCh

    Joined:
    Jun 14, 2013
    Posts:
    19
    Wouldn't that mean that you should also rename your 'VectorLine.color' property to something else? ;)

    I've tried renaming the variable, even though that shouldn't be an issue except for readability with no effect. Grabbing the MeshRenderer and setting it's material's color property directly seems to work though:

    Code (CSharp):
    1. var lineRenderer = line?.rectTransform.gameObject.GetComponent<MeshRenderer>();
    2.  
    3. if (lineRenderer == null) {
    4.         return;
    5. }
    6.              
    7. lineRenderer.material.color = color;
     
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No? "color" isn't a Unity class and there's no chance of interference. e.g., this would fail:

    Code (csharp):
    1. var Color = Color.white;
    This is fine:

    Code (csharp):
    1. var color = Color.white;
    Anyway, as I mentioned your code worked fine, though if you changed it and were using a different material than the default, with a shader that doesn't support vertex colors, that would prevent normal line colors from working.

    --Eric
     
  20. CGDever

    CGDever

    Joined:
    Dec 17, 2014
    Posts:
    156
    Hi Eric5h5!
    I have a problem with 3d line:

    (problem of incorrect stretching of the texture)

    I'm using a standard shader.
    Here is the cs code:
    void Start () {
    m = new Material (lineMaterial);
    // VectorManager.useDraw3D = true;

    linePoints.Add( Vector3.zero );//v0.position );
    linePoints.Add( v1.position - transform.position );
    linePoints.Add( v2.position - transform.position );
    linePoints.Add( v3.position - transform.position );
    linePoints.Add( v4.position - transform.position );

    myLine = new VectorLine("3DLine", linePoints, lineMaterial.mainTexture, ScreenAspect, LineType.Continuous, Joins.Weld);
    myLine.drawTransform = transform;
    myLine.continuousTexture = true;
    myLine.maxWeldDistance = 0;
    myLine.material = m;

    myLine.SetDistances ();
    m.mainTextureScale = new Vector2(1f,myLine.GetLength ()*2f);

    myLine.Draw3DAuto ();
    }
     
  21. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Setting the material's mainTextureScale is unlikely to work; use VectorLine.textureScale instead.

    --Eric
     
  22. CGDever

    CGDever

    Joined:
    Dec 17, 2014
    Posts:
    156
    same result (
     
  23. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Long thin lines in 3D don't generally work very well with texture mapping; dividing lines into smaller segments helps. e.g., 2 segments:

    p1.png

    Result when each segment is divided into 4 smaller segments:

    p2.png

    --Eric
     
  24. CGDever

    CGDever

    Joined:
    Dec 17, 2014
    Posts:
    156
    Hmm, not the best solution. Are you planning to fix this?
     
  25. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    That's inherent in the way 3D hardware works, not anything I have any control over.

    --Eric
     
  26. Divinewings

    Divinewings

    Joined:
    Oct 2, 2017
    Posts:
    3
    Hi Eric5h5!
    Thanks for Vectrosity :)
    I have a question about drawing order.
    I'm using unity IMGUI https://docs.unity3d.com/Manual/GUIScriptingGuide.html interface
    I want to draw some lines on top of GUI, but its always hidden behind. How I can do it?
    http://prntscr.com/hvhm3c

    Tried GUI.depth, 2 cameras with different depth, line.drawDepth. Nothing works :)

    Using this code to create line:
    Code (CSharp):
    1. var line = new VectorLine("Line", new List<Vector2>() {new Vector2(20, 20), new Vector2(150, 150)}, ThinLine,
    2.                     1.0f, LineType.Continuous, Joins.None);
    this code to update params
    Code (CSharp):
    1. public void DrawLine(Vector2 pointA, Vector2 pointB, Color color, float width)
    2.         {
    3.             var line = RenderManager.GetLine();
    4.  
    5.             pointA.y = Screen.height - pointA.y;
    6.             pointB.y = Screen.height - pointB.y;
    7.  
    8.             line.points2[0] = pointA;
    9.             line.points2[1] = pointB;
    10.             line.color = color;
    11.             line.lineWidth = width;
    12.             line.Draw();
    13.         }
    and this to draw
    Code (CSharp):
    1. void OnGUI()
    2.         {
    3.             GUI.Label(new Rect(200, 200, 200, 200), "HELLO WORLD");          
    4.             DrawLine(_pointA, _pointB, Color.blue, 3);
    5.         }
     
  27. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It's not possible; nothing can draw on top of IMGUI. Use uGUI instead.

    --Eric
     
  28. Divinewings

    Divinewings

    Joined:
    Oct 2, 2017
    Posts:
    3
    But I can send you the code which can draw on top... it is possible.
    Proof: http://prntscr.com/hvnphp
     
  29. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The only thing that can draw on top of IMGUI is IMGUI, and Vectrosity doesn't use that, it uses uGUI.

    --Eric
     
  30. Divinewings

    Divinewings

    Joined:
    Oct 2, 2017
    Posts:
    3
    It uses GL. Any plans to add a support for drawing on top of IMGUI? I can share a snippet.
     
  31. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, sorry, there are no plans to use anything other than uGUI for Vectrosity.

    --Eric
     
  32. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
  33. zeninja

    zeninja

    Joined:
    Jun 9, 2012
    Posts:
    8
    Hi, apologies if this has been asked and answered before, but I'm looking for a way to change the rotation of individual segments within a line in Vectrosity. Similar to how the "alignment modes" work in the default line renderer, I'd like to achieve an effect where the line would look as if it's being wrapped around a cylinder. Is that possible?

    Thanks!
     
  34. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Probably an issue with image compression (which should be turned off). Also the images are 3x3 pixels; not sure if that's intentional, since at normal size you can't really see them, and if they're enlarged, they won't look good.

    No, sorry, the design of Vectrosity is that lines face the camera.

    --Eric
     
  35. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hi Eric,

    Thanks for the reply. I turned off image compression, but the issue remains. My end cap seems strangely blurred. Also it's supposed to be 3x3, as they're quite thin lines. The line itself is working great, it's just the cap that seems to be an issue?

    Here's my code:

    Code (CSharp):
    1. void Awake() {
    2.     if (!_setEndCap) {
    3.         VectorLine.SetEndCap("Tracer", EndCap.Back, LineTexture, LineEndCapTexture);
    4.         _setEndCap = true;
    5.     }
    6.  
    7.     CreateVectorLine();
    8. }
    9.  
    10. void CreateVectorLine() {
    11.     Color transparentColor = Color;
    12.     transparentColor.a = 0;
    13.  
    14.     _vectorLine = new VectorLine("Tracer", _points, 3f, LineType.Continuous) {
    15.         material = LineMaterial,
    16.         texture = LineTexture,
    17.         smoothColor = true,
    18.         color = transparentColor,
    19.         endCap = "Tracer"
    20.     };
    21.  
    22.     _vectorLine.Draw3D();
    23.     _vectorLine.rectTransform.GetComponent<Renderer>().sortingOrder = -1;
    24. }
     
  36. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Turn off bilinear filtering. Nothing to do with the code, by the way, it's your import settings and/or the texture itself.

    --Eric
     
  37. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Sadly disabling filtering doesn't solve it either. I have another End Cap texture with exactly the same import settings that seems to work correctly, so I'm completely stumped as to why there's an issue. If I scale it up it remains completely blurred, but both compression and filtering are disabled?
     
  38. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Actually, I forgot that the import settings for the end cap textures don't matter, since they are picked up from the line texture instead. If the line texture has bilinear filtering, then the end cap textures will too.

    --Eric
     
  39. Lipoly

    Lipoly

    Joined:
    Feb 11, 2014
    Posts:
    42
    Hi,

    I'm on an older version of Vectrocity (v5.4.2). I was wondering if there was either a way that I'm missing or perhaps in the newer updates which solve an issue I'm having:

    I'd like to move an existing line to a different position: ie, move a line's GameObject... and have it properly render.

    It appears that code assumes the GameObject is at Vector3.zero and won't display properly if they're not. The lines will move along w/the GameObject, but It seems that the lines get "stretched" (to keep them screen-space constant size) as if they were still at the origin, so they appear all twisted and otherwise not right.

    My use-case is performance-related as well as simply cleaning up my code. Once a line is drawn, the general shape is constant, but the line needs to be placed at different positions in the world. As it is now(as far as I can tell), new points need to be re-fed into Vectrocity with the proper center delta added to them.

    If moving the GameObjects introduce multiple problems, another way to address my issue would be to allow setting a center point/position of a VectorLine wich Vectrocity would use in its calculations instead of assuming origin. I've looked at some Vectrocity code, and I can see places where position.magnitude appears to be used as a distance from the center...I'm guessing places like that would need updating.

    Thanks,
    Philip
     
  40. zeninja

    zeninja

    Joined:
    Jun 9, 2012
    Posts:
    8
    Hi,

    I'm having trouble setting a VectorLine's position in world space for a 3D line. When I set the rect transform's position to the parent object, the values are set, but it seems to be in a different coordinate system. Is there a way to convert from Rect transform space to world space in 3D?

    Thanks!
     
  41. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Vectrosity isn't designed for that; you can do it but should be aware of exactly how it works and what the consequences are. In most cases you should use VectorLine.drawTransform, if you want to use an object to set the position of a VectorLine without directly altering the points in the line.

    3D lines are meshes in the scene like other objects, and shouldn't be parented to objects with RectTransforms. Those are different concepts and not really compatible.

    --Eric
     
  42. zeninja

    zeninja

    Joined:
    Jun 9, 2012
    Posts:
    8
    Thanks for the response, Eric. The problem I'm having is that I can't place the 3D vectorlines relative to another gameobject in the scene. The VectorLines I'm drawing have a Rect Transform and when I try to set their position to be the same as another object's, they do not match up. This is the case whether I give the VectorLine a parent or not, whether I give it a drawtransform or not. Is there something I'm missing here? I'd just like to reliably know where I'm placing the line in world space. Thanks again for the help!
     
  43. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Use VectorLine.drawTransform if you want to use another object to influence the position of the points in a VectorLine.

    --Eric
     
  44. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hi Eric,

    This doesn't seem to fix the issue either. Additionally I'm hoping to use bilinear filtering as I'm looking for the anti-aliasing effect from the documentation. This is the result of turning off filtering:



    Basically I'm trying to have a rounded look at the end of the line (which can obviously look so-rounded due to the line being 1 pixel with fade either side.)
     
  45. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I'd say something's wrong with the texture.

    --Eric
     
  46. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Hi Eric, sorry to keep bothering you. I tried recreating and re-saving the texture a few different ways, but I still end up with the same issue.

    It seems like it might have something to do with how end caps and colours are handled? This is the line with smoothColors on:



    This is the line with smoothColors off:



    (The line is two segments. These screenshots are of the END of the line. At the start is a short segment that has zero alpha, then the other segment begins at alpha=1 and fades down to zero. It creates a nice tapering effect.)

    The colour difference of the semi-transparent edges is most noticeable. Could this be because of the line's segment colours? Maybe fading it down each frame isn't being applied to the end cap or something like that? It does fade down as well, but maybe the alpha is slightly off somehow?

    Finally this is me manually positioning the end cap onto the line texture as sprites in the scene:



    I just wanted to be sure they actually match up, for sanity reasons.

    All of your help is greatly appreciated!
     
  47. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Aha, line colors, I didn't know you were using that. It turns out there's a bug when setting the end cap vertex colors when using smoothColor. For now you can work around that by setting the cap colors specifically with SetEndCapColors.

    --Eric
     
  48. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Great! So that's brought it inline with the second two images in my last post. However there's still the noticeable seam between the end cap and the line texture. I don't suppose there's any other known bugs there? Hehe.
     
  49. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The only thing I can think of is maybe you aren't using any transparent padding around the textures and the alpha is getting stretched a little weirdly at the edges when using bilinear filtering. No seams here, I always use at least 1 pixel of padding to make sure the alpha fades the way I want:

    Screen Shot 2018-01-12 at 12.42.52 PM.png

    --Eric
     
    Last edited: Jan 12, 2018
  50. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Strange. If I add a pixel of transparent pixels as a border of each (and increase the line width by 2) then my line has a huge transparent area at the end of it. If I just put transparent pixels on the line cap, it just adds a space between the line and the line cap. In your example line, is that just three pixels? Or larger?
     
    Last edited: Jan 15, 2018