Search Unity

Vectrosity - Fast and Easy Line Drawing

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

  1. LewisJordan

    LewisJordan

    Joined:
    Sep 5, 2017
    Posts:
    1
    Hey!

    I'm loving Vectrosity so far! The only issue we are running into is that in some orientations the line disappears below the ground. This is when using the 3d line. From looking in the scene view while rotating the game view camera, I can see that the line changes shape (I guess to make the line always look at the camera?). Some of these shapes have sections that are below ground level.

    Here are two images from the game view. They are both the same line, just viewed from different perspectives. The first image shows the line looking correct. The second image shows that some sections are underground.
    upload_2021-5-3_22-41-15.png upload_2021-5-3_22-41-39.png



    Now for the scene view. Again this is the same line, just viewed from different perspectives in the game view.
    upload_2021-5-3_22-45-7.png upload_2021-5-3_22-46-59.png

    Is there a way to resolve this?

    Thanks in advance!
     
    polyflow3d likes this.
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You can draw the line once from the perspective you want, and then not update the line again, but other than that, as you noted, the line does change shape to make it look correct from the current perspective so there's no real way to prevent that.

    --Eric
     
  3. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    And if he draws the line always on top with the shader? I found it a bit strange, that the line during rotation will change it's shape under the ground, while surfaces facing cam is activated. Or perhaps change the shape of the line into a + and disable facing to cam?

    You can also use a tube-mesh with 5 sides and invert the normals of the faces. Looks also pretty nice on transparent materials.
     
    polyflow3d likes this.
  4. Kaven-Co-Games

    Kaven-Co-Games

    Joined:
    Jun 3, 2014
    Posts:
    19
    Been using Vectrosity for a long time, just wanna say thanks Eric. I have been using so many of your tools for years, you do awesome work.
     
    schmosef likes this.
  5. xindexer2

    xindexer2

    Joined:
    Nov 30, 2013
    Posts:
    78
    I'm attempting to avoid destroying and re-instantiating my VectorLines. I am drawing thousands of lines at a time and each line has it's own color assigned to it. Creating a new VectorLine and assigning the colors via SetColors works great on the initial build. After user input, I sometimes need to add to or subtract from the number of segments, I have been using myLine.points3 for this and it works great, all of the points are moved and new ones are added as necessary. The problem is the color array. There is no function myLine.colors32 where I can replace the color array with a new one. SetColors adds a second array to the first and I end up with a mismatch of colors and points.

    Is there a solution to this? Can I dynamically change the colors array?

    If not, how big of a penalty is there in destroying the vectorline and rebuilding it? I've been running into the vertex limit so now I have 10 vectorlines (and counting). Would be nice to just reassign those assets instead of destroying them.

    Thank you for the great product.
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I would not recommend destroying/rebuilding lines. You can use SetColor to set a specific line segment color when adding/removing points. The thing to remember is that for continuous lines, there is one fewer line segment than there are points, and for discrete lines, the number of segments is exactly half the number of points.

    --Eric
     
  7. xindexer2

    xindexer2

    Joined:
    Nov 30, 2013
    Posts:
    78
    SetColor would work but it would require me to loop trough 500 colors per vectorline (and I have 12 vectorlines right now), that's not particularly efficient either. I need a call like points3 but for colors.

    myLine.points3 = energy (which is a List<Vector3> with 1000 points)

    I would like
    myLine.colors = energyColors (which is a List<Color32> with 500 colors

    Could you point me in the right direction where I can extend the class to make this functionality work?

    thank you
     
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I'm not sure why SetColor would require any loops. e.g. if you add a point, would you not then simply call SetColor once with the appropriate color and index, using your energyColors list?

    --Eric
     
  9. xindexer2

    xindexer2

    Joined:
    Nov 30, 2013
    Posts:
    78
    Oh - sorry for not being more accurate.

    When I call myList.points3 = energy, I'm resetting all of the points with a new set which is a different length than the original one. Vectorline is happy to swap out the data and change the length of the list.

    Then I have a completely new List of colors that needs to be assigned to that list of points. So I either loop through all of them or preferably, swap out all of the old colors for the new ones in one call.
     
  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    In that case I'd suggest using SetColors with your color list.

    --Eric
     
  11. SubdivisionCG

    SubdivisionCG

    Joined:
    May 9, 2020
    Posts:
    15
    Hello,
    I bought Vectrosity with the intention of using it for various lines we'll need in our game. Specificially, we have a 3D planet and want to display country borders as well as various road lines.

    Initially I was really excited because the plugin is easy to use. But I just ran a test with a few actual country borders, and the performance is absolutely awful: I have a single VectorLine object with 6000 segments. That's not very much when you need to draw curved splines. And yet my framerate goes from 300 fps without this VectorLine object down to 40 fps. How is this possible? Is this normal?

    To explain what I'm doing: I load up a CSV that I exported from Houdini. It contains 6000 segments (12000 points). I construct one VectorLine object from these point positions. And then I do a Draw3DAuto() inside of the MonoBehavior's Start(), because the lines need to be updated when the camera moves. And that brings me down to 40fps.

    We had previously imported 3D geometry into Unity for our country borders, which came out at around 200,000 polygons. Performance is absolutely fine this way. However, we wanted an easy way to maintain line thickness regardless of camera distance, and Vectrosity seemed perfect. But now with only 6,000 VectorLine segments, way way less than what we'll need, performance is already unusable?
     
    al4nis and polyflow3d like this.
  12. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    6000 segments with Draw3DAuto gets me ~150FPS on an i7, but that's CPU-dependent, so if you have a slow-ish CPU, it will be less. Since 6000 segments is far more than you'd typically see at once anyway, regardless of FPS I'd suggest optimizing by dividing into smaller sectors instead of one giant line, and only have active the ones that are in view.

    --Eric
     
  13. SubdivisionCG

    SubdivisionCG

    Joined:
    May 9, 2020
    Posts:
    15
    The framerates I measured are not from an empty scene, they're from our project. Either way, I strongly disagree that 6000 segments is far more than you'd see. The attached image shows what I am trying to display: that's not exactly overkill, in fact it's heavily reduced in detail from what we need.

    I am very surprised about this. With a thread that's 60 pages long you'd think tons of people would have run into this. What do people use the plugin for? Displaying two dozen straight lines?

    I have three different solutions to the problem, all of which should give lightning fast framerates because the meshes are always static.
    1) Generate a mesh from input points via scripting, then put a shader on it that pushes/pulls the vertices based on camera distance to maintain constant thickness.
    2) Use ECS to instantiate a cylinder onto every line segment and use the same kind of shader as in 2) to maintain thickness.
    3) Use VFX graph to display "lines" by putting particles along the length of each line segment.

    I'll opt for 1), should be quick and straightforward to implement. I just really really expected the plugin to have this kind of functionality.
     

    Attached Files:

  14. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    OK, I didn't realize you were viewing the entire planet at once. By "country borders" I was envisioning a typical TBS-type map. For the vast majority of cases, no, people do not need to display 6000+ line segments all at once. Among others, NASA was using it at one point (don't know if they still do), so I suspect it has some uses. As a somewhat generalized tool, it won't cover every possible use-case.

    --Eric
     
  15. SubdivisionCG

    SubdivisionCG

    Joined:
    May 9, 2020
    Posts:
    15
    I didn't mean to come across as offensive, I'm sure there are plenty of uses for the plugin. I assume it'll come in handy for when we do UI things, and even for the 3D part I'll probably use your VectorLine object to convert input positions into bezier, then extract the positions from the VectorLine object for my own use.

    However, I do think that Draw3D() and Draw3DAuto() are partially "broken". I don't know how these are implemented exactly, but I assume that they reconstruct the entire line. Doing this every frame for a line with thousands of points is obviously costly.

    Our use case is lines that are static. Once generated, they don't change at all, so there is no reason to reconstruct them every frame or ever really, giving this insane performance hit.

    I've now implemented what I mentioned yesterday: I construct a cylindrical mesh for each line segment* then assign a shader that pulls the cylinder's points along their normals based on camera distance. This solution is extremely fast, it gives practically no performance penalty with that same exact geo of 6,000 segments.

    *I use cylinders with 5 sides. Although this creates considerably more geometry than a single quad would I don't have to worry about reorienting the quad towards the camera which I didn't want to bother with right now.
     
  16. xindexer2

    xindexer2

    Joined:
    Nov 30, 2013
    Posts:
    78
    Is it possible to use a single MakeArc to make this image?

    I have all of the start and end points as Vector3s and I have the start and end points as degrees around the circle. I'm really trying to avoid making 50 vector lines to draw a segmented circle. The docs talk about using index to make multiple arcs in one line but I can't figure out the structure.

    Thank you
     

    Attached Files:

  17. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    For example, if you had a line with 20 points (10 segments) and wanted two arcs, the first arc would use 5 for the segments parameter in MakeArc (so it uses 10 points), and the index parameter would stay at the default of 0. The second arc would also use 5 for segments, and 10 for the index parameter.

    --Eric
     
  18. drhousemd

    drhousemd

    Joined:
    Dec 6, 2012
    Posts:
    25
    I was looking to update my Vectrosity package and saw on the Unity Asset Store that the latest version was 5.6.1 (Released: Oct 5, 2020). I had originally bought the asset through starscenesoftware.com, so I tried using my email update link, but the latest version with it is 5.6 (Released: Apr 27, 2018).
    I'm interested in the updated LineMaker utility and would like v5.6.1, can I get a download link?
    email: riaz.ali@gmail.com
     
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Hi, the only difference is that the ability to generate Unityscript code in the LineMaker utility was taken out, so there's no real reason to update.

    --Eric
     
  20. drhousemd

    drhousemd

    Joined:
    Dec 6, 2012
    Posts:
    25
    oh, then why make it a separate patch? also, "removed DLLs due to technical issues with later versions of Unity" could be useful
     
    Last edited: Jul 5, 2021
  21. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Nope, since you can already do that: just remove the DLLs and replace them with the source. It's not an improvement or anything, rather the opposite actually.

    --Eric
     
  22. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Why do I get "Line must be attached to a canvas" in the 2d view? The line is a child of a screenspace canvas (not the only canvas in the scene). I just right clicked on the canvas in the hierarchy and selected UI->VectorLine.
     
  23. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    That should work, and it does when I tried it just now. I can't think of anything that would cause it not to work, but in the worst case you could create the line by itself and then drag it from the default canvas to the one you want.

    --Eric
     
  24. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Thanks, but this does not work either. I created a VectorLine and it automatically created a canvas. The line attached under this canvas works. If I drag this line to my canvas, it no longer works. If i drag it back to the vectorline canvas, it works. I set all of the components and values on the vectorline canvas to match my canvas. The only difference is the object name. The same happens when I drag the line from one to the other, works under vectorline canvas, does not work under my canvas.
     
  25. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The only thing I can think of is that the canvas you're trying to use is the child of another object.

    --Eric
     
    Innovine likes this.
  26. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Yes, that is it. Works now, thanks. I'm wondering why this is a limitation though,.. I've been drawing lines from code on this canvas for a while now. Seems like this is just some limitation in the editor? I also notice that I have to switch to Overlay to draw the lines, but it's fine to switch back to Screen Space - Camera once drawn :/
     
    Last edited: Jul 9, 2021
  27. cryptoforge

    cryptoforge

    Joined:
    Jan 21, 2015
    Posts:
    60
    Does this require a dedicated camera to render like the LineRenderer?
     
  28. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Lines can use a canvas, or can be rendered in the scene using your camera of choice. Also for lines that use Vector3 world-space coords, the calculations to make the lines a constant width are linked to a camera since they are rendered from its perspective.

    --Eric
     
  29. cryptoforge

    cryptoforge

    Joined:
    Jan 21, 2015
    Posts:
    60
    I don't want to use a dedicated camera. Just want to put lines on a canvas overlay. Currently, I am already using a camera for LineRenderer which is wasting FPS and I want to get rid of it. Will I be able to do it with this asset?
     
  30. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    As long as the line coords are 2D (Vector2), then it doesn't need a camera at all. If the coords are 3D, it needs some kind of camera for the line orientation calculations, however the camera doesn't actually have to be active, it just needs to exist.

    --Eric
     
    cryptoforge likes this.
  31. cryptoforge

    cryptoforge

    Joined:
    Jan 21, 2015
    Posts:
    60
  32. whisp

    whisp

    Joined:
    Jun 21, 2014
    Posts:
    19
    Hello!

    I've created a shader with Shader Graph (Universal) and it works fine with the line. But after animating it, the line doesn't show the animation, it's static. Is it possible to use an animated shader? What is required to have the line display the animation?

    Edit: I'm drawing a 2D line on a canvas in the UI
     
    Last edited: Jul 24, 2021
  33. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I can't answer that without knowing what the shader does, but my guess is that it depends on attributes the line mesh doesn't have by default, such as normals and tangents. If that's the case, then you could try the AddNormals and/or AddTangents functions.

    --Eric
     
  34. whisp

    whisp

    Joined:
    Jun 21, 2014
    Posts:
    19
    Thank you for the quick reply. The shader is pretty simple, unlit. I still tried AddNormals and AddTangets, but it changed nothing. The shader uses noise and time to create an animated color and alpha.

    shader.png

    In the shader the "waves" move, but on the line they don't.
    Base Color and Alpha.png

    This is how I initialize the line, while m_LineMat is the material with the mentioned shader:
    init line.png

    Edit: Possibly there's something wrong with my Unity setup. I had installed both, URP and HDRP, because I thought I need to use URP for GUI. I deinstalled URP and will see if I can get the line showing up correctly with HDRP.
     
    Last edited: Jul 25, 2021
  35. whisp

    whisp

    Joined:
    Jun 21, 2014
    Posts:
    19
    Switched to legacy renderpipeline and am using the Amplify Shader Editor instead. Everything works fine now.
    By the way, Vectrosity is awesome!
     
  36. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Why does this not work:

    Code (CSharp):
    1.     void Start()
    2.     {
    3.         List<Vector3> points = new List<Vector3>();
    4.         myLine = new VectorLine("Equator", points, width);
    5.         myLine.lineType = LineType.Continuous;
    6.         GenerateCircle();
    7.         myLine.Draw3DAuto();
    8.     }
    9.  
    10.     private void GenerateCircle()
    11.     {
    12.         for (int i = 0; i < circleResolution + 1; i++)
    13.         {
    14.             myLine.points3.Add(Vector3.zero);
    15.         }
    16.  
    17.         myLine.MakeCircle(Vector3.zero, Vector3.up, radius, circleResolution);
    18.     }
    I don't see anything in the scene. When I inspect the line, I can see that it's points3 list is correct, however the Line Vertices is nothing but zeros.

    If I have no canvas in the scene, i don't see a vectrosity one being created. If I do have a canvas and i assign it to the line with SetCanvas() I dont see any difference.
     
  37. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Draw3D doesn't use a canvas; the line is an object in the scene. You can just initialize a List with the number of points, so there is no need to use Add in a loop, and therefore no need for the GenerateCircle function. This works fine:

    Code (csharp):
    1.     void Start()
    2.     {
    3.         myLine = new VectorLine("Equator", new List<Vector3>(circleResolution+1), width, LineType.Continuous);
    4.         myLine.MakeCircle(Vector3.zero, Vector3.up, radius, circleResolution);
    5.         myLine.Draw3DAuto();
    6.     }
    Make sure the variables make sense; i.e. if radius is 0 then all the points would be 0.

    --Eric
     
  38. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    The width and radius are set fine. The points3 array does make a circle. However, Line Vertices are all zero, and of course nothing shows.
     
  39. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I tested it and it works as expected. Make sure the camera is positioned where you would be able to see it.

    Screen Shot 2021-09-12 at 10.08.15 AM.png

    --Eric
     
    twobob likes this.
  40. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    That is not much help to me. Why are Line Vertices all zero?
     
  41. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Because the line isn't in view. I'm not really sure what else to add...the code works, you can see the screenshot. If the camera can't see the line it won't be drawn and the vertices will be zero. Point a camera at the line where at least part of it would be visible, and make sure the variables make sense, i.e. the radius isn't 100K units or something.

    --Eric
     
  42. galran

    galran

    Joined:
    Oct 3, 2017
    Posts:
    7
    Hi,

    I’m getting these kind of errors in my scene whenever an object with lines is destroyed or disabled:

    "Coroutine 'OnBecameInvisible' couldn't be started because the game object 'Sphere' is being deactivated!"

    I’m also getting one error per existing object whenever I stop playing the scene.
    Any idea how to gracefully delete a line object without getting this error?

    Unity Ver: 2021.1.11f1. Vectrosity: 5.5.

    Thanks
     
  43. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Upgrade to Vectrosity 5.6.

    --Eric
     
  44. galran

    galran

    Joined:
    Oct 3, 2017
    Posts:
    7
    well, apparently I'm using version 5.6.1 (the coding documentation still says 5.5).
    the error is still there....any other ideas?
     
  45. galran

    galran

    Joined:
    Oct 3, 2017
    Posts:
    7
    I just created a new project.

    Installed Vectrosity 5.6.1 using the package manager.

    Installed the demos by double clicking on the package in the project window and importing it.

    Run the _Simple3DObject scene from the Demos/_scenes folder, and when I stop the scene, I get 3 error messages:

    Coroutine 'OnBecameInvisible' couldn't be started because the game object 'Cube1' is being deactivated!

    Coroutine 'OnBecameInvisible' couldn't be started because the game object 'Cube3' is being deactivated!

    Coroutine 'OnBecameInvisible' couldn't be started because the game object 'Cube2' is being deactivated!
     
  46. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Wait, that's a different issue than what I was thinking of, sorry. Newer versions of Unity started doing that for some unknown reason (internal changes in GameObject lifecycle management or something?), but since no user code is actually running when it happens, there doesn't seem to be any possibility of preventing those messages. They only occur in the editor when stopping play mode and don't cause any actual problems, so while it's a bit annoying, I had to conclude that ignoring them was the only real option.

    --Eric
     
  47. galran

    galran

    Joined:
    Oct 3, 2017
    Posts:
    7
    Well, if that was true i would not have a problem with it.

    Unfortunately, my problem is that I’m using Vectrosity in a WebGL component, and these errors, which appear every time an object’s VISIBILITY CHANGE, propagate into the browser console without the ability to stop them (disabling logging altogether doesn’t seem to help).

    So, I’m ending with a flood of error messages in the browser console, which makes it hard to debug any of the real issues ☹

    I’ll try to experiment with hacking the Vectrosity object manually before destroying it and see if I can figure anything out.


    Thanks
     
  48. galran

    galran

    Joined:
    Oct 3, 2017
    Posts:
    7
    Seems that the culprit, at least in my case, is the [VisibilityControl] script. If I destroy an object with this script active on it, I get the error message. Destroying the component before destroying the game object seems to solve the problem for me.

    Probably it’s a timing issue with coroutines and what not…thanks for the help.
     
  49. PanicEnsues

    PanicEnsues

    Joined:
    Jul 17, 2014
    Posts:
    187
    Hi Eric,

    I've started getting some null reference exception reports from players on my latest build; top of the call stack is:

    UnityEngine.UI.Graphic.SetVerticesDirty () (at <00000000000000000000000000000000>:0)
    Vectrosity.VectorLine.SetColor (UnityEngine.Color32 color, System.Int32 index) (at <00000000000000000000000000000000>:0)


    The errors only seem to come from Android devices, but I've not been able to repro it on any device or platform.

    Have you seen this error before? Any ideas what would cause it?

    -Scott
     
  50. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Sorry, I've never seen or heard of anything like that before. Given that it's only on Android, and seems to be in UnityEngine.UI, I'd guess it's a bug in whatever version of Unity you're using. If possible, I'd suggest trying a different version.

    --Eric