Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

★ LINEFY ★ - GPU powered, cross-platform lines

Discussion in 'Assets and Asset Store' started by polyflow3d, Apr 23, 2020.

  1. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    Finally, the most powerful line drawing library for Unity is available in the Asset Store



     
    Last edited: Apr 23, 2020
    dirkjacobasch and SugoiDev like this.
  2. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    ♦ import quad wireframe ♦

     
    Last edited: Apr 25, 2020
  3. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    ♦ use custom texture atlas for Dots ♦

     
    Last edited: Apr 25, 2020
  4. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    ♦ draw screen space ♦

     
    Last edited: Apr 25, 2020
    SugoiDev likes this.
  5. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    ♦ use custom textures for Lines ♦
     
  6. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    ♦ draws hundred of thousands dots in one draw call ♦
     
  7. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    509
    This looks really interesting. I have some questions:

    1. Does Linefy handle world space 3D lines with a constant pixel width regardless of distance from the camera? For example, a line near the camera and a line 2000 units away both taking up a width of 1 pixel on the screen?

    2. I'm not sure if you've used Vectrosity before, but I'm wondering if there's a difference in performance.

    3. Have you tested the lines with HDRP TAA? If rotating a camera quickly with lines in view, do the lines have a lot of ghosting artifacts? If the lines are already anti-aliased, is it possible to exclude them from generating motion vectors?

    4. If a 3D line passes through an object, is it possible to dim the part of the line that is inside the object?

    5. Is there a simple API for creating circle outlines (with variable levels of vertices), square outlines, and triangles of varying sizes?

    Thanks!
     
  8. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    Yes. Lines, Polylines and Dots behaves like a regular 3d object , except that the thickness in pixels will always be the same (that specified). Also it not cast and not receive the shadows.

     
    Korindian and SugoiDev like this.
  9. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    As far as I know, Vectrosity uses scripts and WorldPointToScreen() (or something like that) for each camera to positioning a lines vertices. Linefy does all the heavy calculations in the vertex shader. So I assume that Linefy is much faster, espetially on powerfull GPU. But Vectrosity and the standard LineRenderer have one advantage - you can specify your own material for the lines. And in Linefy, the only two fixed materials are used - unlit transparent or unlit opaque. Keep this in mind.
     
    Korindian likes this.
  10. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    I am not familiar well with render pipelines. I did one test and it looks good in my opinion.



    If you provide me a custom test HDRP scene, I will render it and show the result.
     
    Korindian likes this.
  11. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    Anti Aliasing is adjustable feature, not fixed. This is implemented as border transparency fadeout , measured in pixels, called Feather. Feather effect are independent of width.

     
    Korindian likes this.
  12. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    There are no ready-made figures in Linefy. But there is a super clear API for creating any shapes. For example, here is a script that creates a circle.

    Code (CSharp):
    1. using UnityEngine;
    2. using Linefy;
    3.  
    4. [ExecuteInEditMode]
    5. public class ForumExample : MonoBehaviour
    6. {
    7.     [Range(3,64)]
    8.     public int segments = 8;
    9.     public bool isClosed = true;
    10.     [Range(0,40)]
    11.     public float width = 10;
    12.     public float radius = 10;
    13.     [Range(0,10)]
    14.     public float feather = 2;
    15.     public Color color = Color.white;
    16.     Polyline circlePolyline;
    17.  
    18.     void Update()
    19.     {
    20.         if (circlePolyline == null) {
    21.             circlePolyline = new Polyline(segments, true, 0, false);
    22.         }
    23.         circlePolyline.count = segments;
    24.         for (int i = 0; i<segments; i++) {
    25.             float angle = i / (float)segments * Mathf.PI * 2;
    26.             Vector3 vertexPos = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle)) * radius;
    27.             circlePolyline.SetPosition(i, vertexPos);
    28.         }
    29.         circlePolyline.isClosed = isClosed;
    30.         circlePolyline.feather = feather;
    31.         circlePolyline.widthMultiplier = width;
    32.         circlePolyline.colorMultiplier = color;
    33.         circlePolyline.Draw(transform.localToWorldMatrix);
    34.     }
    35. }
    result:

     
    Korindian likes this.
  13. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    509
    Great, thanks for the in-depth replies. If it is indeed faster because it handles calculations in the vertex shader, I will pick this up in the near future. Unlit lines are what I'd be using it for anyway.

    Would you be able to answer question #4 about dimmed lines in my previous post by any chance? The reason I'm asking is that there's another similar asset that just came out as well that has Z-testing to reduce opacity, and I was missing that from Vectrosity as well. Thanks.
     
  14. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    I apologize, I do not understand the meaning of the "dimmed" term.
    There is a temporarily non-documented feature transparency -fading depending on the distance in the shader level. You can see it on the cyan grid in the first demo scene.
    Also, you have full generic control over every lines point: color (include transparency), thickness, position, uv-coordinates.
     
    Last edited: Apr 30, 2020
  15. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    509
    Sorry I wasn't more clear. Please see the following link:

    https://arongranberg.com/aline/features

    At the very bottom of that page, there is a section called Z-Testing. If you click on that picture and look closely, you can see that the blue line on the left side passes through or behind the top-left orange cube. That part of the blue line which is behind or inside the orange cube is still visible, but dimmed (less bright) or more transparent.

    I wouldn't be able to achieve that by setting the transparency of a point, because the line may be intersecting a mesh in the middle of the line, as it is in that picture. It seems like some Z-testing would be needed.

    Just wondering if that's possible with Linefy.
     
  16. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    I guess the orange cube uses a transparent shader.
    Linefy is not able to shade objects that are rendered in front of him.
     
    Last edited: May 2, 2020
  17. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    ♦ there is enough productivity to draw realtime♦
     
    tonialatalo likes this.
  18. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    ♦ cross platform♦
     
  19. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    Comparison of Linefy`s polyline and native LineRenderer

     
  20. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,041
    Heya, I was about to let you know that the image you posted didn't show up for me in the normal forum view, or even when I clicked on it to open it, but strangely, when I clicked "reply" on your message to tell you, it shows up and plays in the reply screen.


    The popup doesn't work, then behind it you can see your post, which also doesn't, but my reply does. I guess it must be something on Unity's end?

    ---

    That was not the intention of my reply initially, I was going to see if you happen to have any performance comparisons for similar situations between the built-in line rendering capabilities of Unity vs Linefy? I don't doubt that it is fast, I just am quite interested in seeing *how* fast, in comparison to other things.

    Also, is the package able to be ran/rendered from within Jobs and in ECS?

    I am currently using the package ALINE that @Korindian mentioned above to render some lines and things for some tools I am making for my game. The main reason being, it can render from within threaded and even Burst compiled jobs. While, at the moment I am just making some tools for edit time, I plan on also using similar things in different situations in-game.

    Based on what I am seeing so far, I like the features and customization that Linefy offers, such as the quick and easy width and segmentation adjustments and it looks like it comes with tools for creating/converting meshes to drawn lines, which would be great as ALINE doesn't have anything like that, I had to manually create this arrow below line by line.



    Honestly, I was fine with that, though. I figured, how else would I get what I wanted? If Linefy has tools to help with that, then that is all the better, as it would allow me to more quickly implement other custom shapes and things.

    This definitely looks like an interesting package, it may be able to provide some additional use cases that I might otherwise have not been able to explore.

    Really, the only concern is that my current project and all of my future projects I will be doing going forward will be making use of ECS and the Job system as much as possible, so it would be nice to have some assurance that if I do get this, that it supports these systems.

    Thanks,
    -MH
     
    polyflow3d likes this.
  21. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    Hey.
    I think this is some kind of forum bug with pictures.

    I have not made a performance comparison, but I'm ready to do it if you advise what it should include.

    The Job system (native array) is not directly supported and I had no plans to add it in the next release. As far as I understand, the Job System and ECS can only improve performance if you use complex calculations for thousands of points. But Linefy consumes very little CPU time if you do not update line`s positions, colors, thickness or UV.

    But nevertheless, I plan to do some platform-specific optimizations that will speed up the vertices update several times.
    Now the performance of the Linefy is limited by the API capabilities that are available for the webgl.
     
  22. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    Take a look how easy to draw arrow in 3ds max and use it as wire object in Unity.
     
    MostHated likes this.
  23. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,041
    Wow, nice. :eek: I actually ended up buying this already last night, lol.

    I played around with the examples a bit (though, the flow of starting from the "main" scene and trying to use the "next" button doesn't work because some of the scenes have no UI, so you can't continue) and I am quite excited about having a go at the custom editor handles and graphs.

    I would be trying to implement them already, but I was already working on trying to get tweening/animation working consistently when selecting things in the scene view at edit time and I want to get that working how I expect it should first.

    The reason I asked about trying to run things within a job was it can potentially slow a job down a ton when you have to try and do workarounds to get data back out for something that can only run on the main thread (such as, if I want to visualize a vehicles assigned waypoint path as it is navigating), instead of being able to run it directly from within the job. I suppose though, that is why it's good to have multiple assets available, some are best for X situation, others are best for Y.
     
    polyflow3d likes this.
  24. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    Assets\Plugins\Linefy\(can be deleted) Examples\EditorHandles

    Thank you a lot. I hope this asset will be usefull. It has great potential, and I think it will be the leading asset for drawing lines in the Unity because it uses the most optimal, GPU-friendly, algorithm to draw lines. At this time, you can ask me to implement literally any feature for your needs. I will also be grateful for the your review in AS.

    The interface for switching scenes can be broken, because examples are so delicate that they do not add themselves to the build of your project :) You need to open these scenes yourself, or add them to Scenes in Build.

    Editor Handles examples located in two scenes:
    Assets\Plugins\Linefy\(can be deleted) Examples\EditorHandles
    Assets\Plugins\Linefy\(can be deleted) Examples\HandlesQuickStart


    Creation of Handles in Unity is quite confusing, for advanced information you can see how the Assets\Plugins\Linefy\Editor\Handles\Linefy.Vector3Handle.cs is maded .

    In Vector3Handle and Matrix4x4Handle the Linefy is used there only for drawing visual graphics, the rest of the code is identical as if you were using Handles.DrawLine or GL.draw.
     
    MostHated likes this.
  25. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,041
    I made sure first thing that the scenes were in the build list. Here is what happens.



    I got the animation I wanted working, so I had a go at making a new indicator using Linefy. It took all of 15 seconds. It is quite nice, for sure.



    I am guessing that the actual mesh renderer and what not are required to remain on the game object for it to continue to function? I am definitely going to play around with some more things and see what I can come up with now that I have the animation figured out.

    ***-- Edit. I feel it's becoming much harder than it should be, and I think I am just missing something, but I can't for the life of me make just a normal dashed line. What is the proper way to go about this?

    I just want to replace my current Handles.DrawDottedLine that is like this below, that I used when connecting waypoints. (just a single straight line, though.)

     
    Last edited: Jul 19, 2020
    polyflow3d likes this.
  26. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217

    To draw dashed lines you should assign dashed texture. ( For example this one )
    Then assign texture offset for line`s points to dashes have uniform length. In example I use world distance between vertices and assign it to second vertex of line.
    There is bug in Lines.SetTextureOffset() functions so please use indexer Lines[] to assign each line structure.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Linefy;
    5.  
    6. [ExecuteInEditMode]
    7. public class LinefyDemo_DashedLines : MonoBehaviour
    8. {
    9.     public Transform point0;
    10.     public Transform point1;
    11.     public Transform point2;
    12.     public Transform point3;
    13.     Lines lines;
    14.     public Texture2D dashedTexture;
    15.     public float textureScale;
    16.  
    17.     void Update()
    18.     {
    19.         if (lines == null) {
    20.             lines = new Lines(3);
    21.             lines.transparent = true;
    22.             lines.feather = 1;
    23.         }
    24.         lines.texture = dashedTexture;
    25.         lines.textureScale = textureScale;
    26.  
    27.         Vector3 p0 = point0.position;
    28.         Vector3 p1 = point1.position;
    29.         Vector3 p2 = point2.position;
    30.         Vector3 p3 = point3.position;
    31.  
    32.         lines[0] = new Line(p0, p1, Color.white, Color.white, 3, 3, 0, (p0 - p1).magnitude);
    33.         lines[1] = new Line(p0, p2, Color.white, Color.white, 3, 3, 0, (p0 - p2).magnitude);
    34.         lines[2] = new Line(p0, p3, Color.white, Color.white, 3, 3, 0, (p0 - p3).magnitude);
    35.    
    36.         lines.Draw();
    37.     }
    38. }
     
    Last edited: Jul 19, 2020
  27. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    Mesh Renderer is nor required. Linefy internally uses Graphics.DrawMesh() or DrawMeshNow() for OnSceneGUI drawing.
    If you want to draw stuff in local coordinates then use Draw(Matrix4x4) overload. Empty Draw() uses identity matrix i.e. worldspace.
     
  28. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,041
    Thanks a bunch for that. It looks like I was pretty close with what I was attempting before, but It might have been the offset that was throwing things off if that is having an issue.

    Code (CSharp):
    1.  
    2. var lines = new Lines(1)
    3. {
    4.     transparent = wpConnectorTransparent,
    5.     feather = wpConnectorFeather,
    6.     widthMultiplier = wpWidthMultiplier,
    7.     [0] = new Line(GetSelectionPivot(), worldMousePos, wpConnectorColor, wpConnectorColor2, wpWidthMultiplier)
    8. };
    9. lines.texture = lineTexture[2];
    10. lines.textureScale = textureOffset[4];
    11. lines.Draw();
    12.  
    When that didn't work, I tried this as well.
    Code (CSharp):
    1.  
    2.  
    3. var path = new Polyline(
    4.     Selection.activeGameObject.name,
    5.     2,
    6.     wpConnectorTransparent,
    7.     wpConnectorFeather,
    8.     false,
    9.     lineTexture[0],
    10.     textureOffset[2],
    11.     (int) textureOffset[3]
    12. );
    13.  
    14. path.SetPosition(0, GetSelectionPivot());
    15. path.SetPosition(1, worldMousePos);
    16.            
    17. path.SetColor(0, wpConnectorColor);
    18. path.SetColor(1, wpConnectorColor2);
    19.            
    20. path.SetTextureOffset(0, textureOffset[0]);
    21. path.SetTextureOffset(1, textureOffset[1]);
    22.            
    23. path.SetWidth(0, wpWidthMultiplier);
    24. path.SetWidth(1, wpWidthMultiplier);
    25.            
    26. path.Draw();
    I was mostly just trying whatever I could think of, lol. Hopefully, what you shared does the trick. I am about to test it out.
     
    polyflow3d likes this.
  29. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,041
    Ok, so it looks like I have discovered why mine kept looking weird. I am not exactly sure what is going on here, but what you can see in the video below is this:

    When I activate my line in OnSceneGui (in a static class which is listening for and handling scene view selection). The start of the line from the waypoint uses a fixed Vector3 position value, which in this instance end up using this code:

    Code (CSharp):
    1. Transform[] transforms = Selection.transforms;
    2.  
    3. if (transforms == null || transforms.Length == 0)
    4.     return Vector3.zero;
    5.  
    6. if (trans.Length == 1)
    7.     return transforms[0].position;
    Then the other end of the line following the mouse is using this:

    Code (CSharp):
    1.         private static Vector3 GetMousePosition()
    2.         {
    3.             return HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
    4.         }
    The above is when the mouse is moving around and not near a waypoint, when it is near a waypoint, instead of using the above GetMousePosition(), it switches to using the gameObject.transform.position of the waypoint under the mouse.

    For some reason, when the line is using :

    p0 = Selection.transforms[0].position;
    p1 = gameObject.transform.position;

    it is fine, but when using:

    p0 = Selection.transforms[0].position;
    p1 = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;

    The line stretches/scales non-uniformly, it looks like. In the video, you can sort of see that close to the base of the selected waypoint the arrow texture starts off fairly reasonable, but as it gets closer to the mouse, it ends up stretching more and more, then as I move the mouse further away, the stretching gets worse instead of, I guess you could say, addiing additional texture segments as you would expect. Once I put it over the waypoint, the scale/stretching becomes fine.

     
  30. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    Code (CSharp):
    1.  return HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
    returns the point that is on the near plane of the frustrum your editor's camera! I suppose this is not what you need.
     
  31. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,041
    I figured something like that would be the case. I have an idea of something to try, I will see how it works and report back.
     
  32. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,041
    Shoot, nevermind, that didn't work.

    Code (CSharp):
    1. private static GameObject cursor = new GameObject();
    2.  
    3. worldMousePos = GetMousePosition();
    4. cursor.transform.position = worldMousePos;
    5.  
    6. Vector3 p0 = cursor.transform.position;
    I thought that if I created a new GameObject, took the mouses position, assigned it to the new gameobject.transform.position, then used that as the position of the line, it might help, but unfortunately the results were the same.
     
  33. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    If the line passes through the camera near plane, it may cause distortion. This is an extremely rare case, so I decided not to complicate the shader by checking this situation for performance reasons. You can try adding a little distance from the frustrum and the distortion should disappear.

    Code (CSharp):
    1. return HandleUtility.GUIPointToWorldRay(Event.current.mousePosition)GetPoint(0.01f);
    But I assume that you want to draw a line in world space, not in camera coordinates. The line should lie on the floor, and its points should be y = 0. Am I right?

    To do this, you need to find the intersection of the mouse-ray with the plane of the ground.
     
  34. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    To find the intersection of the mouse with the ground, you can use such a function

    Code (CSharp):
    1.         Vector3 RayToGround() {
    2.             Plane floor = new Plane(Vector3.up, Vector3.zero);
    3.             Ray r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
    4.             float d = 1;
    5.             floor.Raycast(r, out d);
    6.             return r.GetPoint(d);
    7.         }
     
    MostHated likes this.
  35. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,041
    Perfect. Works just as expected now. I definitely appreciate the help on that.

    ** Edit, I did notice that it only lays flat on the ground if the line is running parallel with the camera view, but really, that isn't super important.
     
    Last edited: Jul 20, 2020
    polyflow3d likes this.
  36. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,041
    What would be the ideal way to go about trying to offset a line to it's right if you were looking at it parallel to the camera view, and the origin is closest to the camera, the destination is directly beyond that?

    My pedestrian waypoints are bidirectional, but the lines end up overlapping and it makes it a bit more difficult to see at a glance if a particular set of waypoints have both directions set.

    In the image below, the left side is how it ends up when there is a line going from one point to another, and then another line going in the opposite direction, overlapping. I am looking for a way to offset it, as seen on the right side of the image.

    Do you have any recommendations?

     
  37. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    217
    I can suggest a texture with two stripes. See how it looks.


    I used this method in the molecules demo.
    I am using a simple texture atlas on which two samples are drawn - with a single line and with a double one. In order to draw a single line, I specify texture coordinates f 0, 0.5 for double line and 0.5, 1 for a single line



    demo package
     
unityunity