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. Dismiss Notice

★ LINEFY ★ GPU powered drawing: lines ╳ polylines ≋ dots ⠇

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

  1. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297
    1) This is an bug on Unity side (seems like some of Unity built in shader variables return wrong values on your platform)
    2) I can not reproduse this bug
     
  2. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297
    This is an common transparent geometry issue not related with linefy.
    Use opaque mode to proper sorting.
     
  3. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297
    use this function to find distance in pixels fron screen point to polyline:

    Code (CSharp):
    1. using UnityEngine;
    2. using Linefy.Internal;
    3.  
    4. namespace Linefy{
    5.     public static class PolylineExtension {
    6.  
    7.         public static float GetScreenDistance(this Polyline pl, ref int segmentIdx, ref float segmentPersentage, Matrix4x4 matrix, Camera cam, Vector2 screenPoint) {
    8.             float minDist = float.MaxValue;
    9.             int minus = pl.isClosed ? 0 : 1;
    10.             for (int i = 0; i < pl.count - minus; i++) {
    11.                 float lv = 0;
    12.                 int idxa = i;
    13.                 int idxb = i + 1;
    14.                 if (idxb >= pl.count) {
    15.                     idxb = 0;
    16.                 }
    17.  
    18.                 Vector3 wa = pl.GetPosition(idxa);
    19.                 Vector3 wb = pl.GetPosition(idxb);
    20.  
    21.                 Vector2  a = cam.WorldToScreenPoint( matrix.MultiplyPoint3x4(wa) );
    22.                 Vector2  b = cam.WorldToScreenPoint( matrix.MultiplyPoint3x4(wb) );
    23.  
    24.                 if (wa.EqualsApproximately(wb)) {
    25.                     lv = 0;
    26.                     minDist = Vector3.Distance(a, screenPoint);
    27.                     continue;
    28.                 }
    29.  
    30.                 Vector2 _ab = b - a;
    31.                 float _length = _ab.magnitude;
    32.                 float _length2 = _length * _length;
    33.                 Vector2 ap = screenPoint - a;
    34.                 float u = Vector2.Dot(ap, _ab) / _length2;
    35.                 Vector3 nearestPoint = Vector3.zero;
    36.                 if (u < 0) {
    37.                     nearestPoint = a;
    38.                     lv = 0;
    39.                 } else if (u > 1) {
    40.                     nearestPoint = b;
    41.                     lv = 1f;
    42.                 } else {
    43.                     nearestPoint = a + _ab * u;
    44.                     lv = u;
    45.                 }
    46.                 float d = Vector2.Distance(nearestPoint, screenPoint);
    47.  
    48.                 if (d < minDist) {
    49.                     segmentIdx = i;
    50.                     segmentPersentage = lv;
    51.                     minDist = d;
    52.                 }
    53.  
    54.             }
    55.             return minDist;
    56.         }
    57.  
    58.     }
    59. }  
     
  4. TheFlyHawk

    TheFlyHawk

    Joined:
    Mar 23, 2016
    Posts:
    56
    var line = go_line.GetComponent<Linefy.EditablePolyline>();
    “polyline” are not public and cannot access GetScreenDistance().

    Polyline _polyline;
    Polyline polyline {
    get {
    if (_polyline == null) {
    _polyline = new Polyline(properties);
    }
    return _polyline;
    }
    }
     
  5. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Welcome back!
     
    polyflow3d likes this.
  6. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    I am curious how I might simulate a camera and its perspective correction, to convert 3d points into 2d ones.
    My code looks something like this:
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         var persp = Matrix4x4.Perspective(fov, aspect, 1, 40);
    4.         int i = 0;
    5.  
    6.         foreach(var point in targets)
    7.         {
    8.             var m = point.transform.worldToLocalMatrix * persp;
    9.             var t = m.MultiplyPoint(point.transform.position);
    10.             t = Vector3.ProjectOnPlane(t, transform.forward);
    11.  
    12.             dots.SetPosition(i, t);
    13.             i++;
    14.         }
    15.  
    16.         dots.Draw(transform.localToWorldMatrix);
    17.     }
    This kind of works... i see my dots and they even look to be perspective converted, but when I rotate the game object this script is on, the dots (which form a cube) do rotate, but they move from side to side too. If I move the game object, i don't see a change. It's like the viewpoint is not correct. How do I improve this so I could move and rotate the gameobject as if it is a normal camera?

    My ultimate goal is to get these dots rendered to a render texture. Can I do anyuthing with material.SetMatrix() ?

    An alternative would be to place the dots at the targets in world space, and use a normal unity camera to render them. I at least know how to do this, but I was hoping the above matrix work would be quicker. Any thoughts? Screenshot 2022-06-16 210638.png
     
    polyflow3d likes this.
  7. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    I have some dots code which works when I do this:
    Code (CSharp):
    1.         dots.Draw(transform.localToWorldMatrix;
    The dots show up in the scene view, and on both cameras in my scene. However, when I try to draw it only on one camera:
    Code (CSharp):
    1.         dots.Draw(transform.localToWorldMatrix, RadarCam);
    no dots show up anywhere.
    Why is this?
     
  8. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297
    If I correctly understood the task you need a projection of world points on a plane?

    I would like to advise you to use the intersection of a ray and a plane.

    It is also possible to move the displayed geometry along the camera's line of sight using viewOffset property in order to eliminate the intersection with other objects. Note that this is a shader effect and it affects the view from all cameras.

     
  9. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297
    This is example script where shown how to project world space positions on plane builded from given distance from camera


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Linefy;
    5.  
    6.  
    7. [ExecuteInEditMode]
    8. public class InnovineExample : MonoBehaviour
    9. {
    10.     public enum MethodType {
    11.         ViewOffset,
    12.         RaycastPlane
    13.     }
    14.  
    15.     Dots _dots;
    16.     Dots dots {
    17.         get {
    18.             if (_dots == null) {
    19.                 _dots = new Dots(4);
    20.             }
    21.             return _dots;
    22.         }
    23.     }
    24.  
    25.  
    26.     public Camera cam;
    27.     public Transform[] items;
    28.  
    29.     public MethodType method;
    30.  
    31.     [Header("View Offset")]
    32.     public float viewOffset;
    33.  
    34.  
    35.     [Header("RaycastPlane")]
    36.     public float cameraPlaneOffset = 1;
    37.  
    38.     public Color color = Color.white;
    39.     public float width = 20;
    40.  
    41.     void Update()
    42.     {
    43.         int markersCount = 0;
    44.         for (int i = 0; i< items.Length; i++) {
    45.             markersCount += items[i] == null ? 0 : 1;
    46.         }
    47.         dots.count = markersCount;
    48.  
    49.         dots.colorMultiplier = color;
    50.         dots.widthMultiplier = width;
    51.  
    52.         if (method == MethodType.ViewOffset) {
    53.             ViewOffsetMethod();
    54.         } else if (method == MethodType.RaycastPlane) {
    55.             RaycastplaneMethod();
    56.         }
    57.  
    58.         dots.Draw();
    59.     }
    60.  
    61.     void ViewOffsetMethod() {
    62.         int counter = 0;
    63.         for (int i = 0; i < items.Length; i++) {
    64.             if (items[i] != null) {
    65.                 dots.SetPosition(counter, items[i].position);
    66.                 counter++;
    67.             }
    68.         }
    69.         // assign viewOffset property
    70.         dots.viewOffset = viewOffset;
    71.     }
    72.  
    73.  
    74.     void RaycastplaneMethod() {
    75.         Vector3 cpos = cam.transform.position;
    76.         // construct camera aligned plane
    77.         Plane p = new Plane(cam.transform.forward, cam.transform.position + cam.transform.forward * cameraPlaneOffset);
    78.         int counter = 0;
    79.  
    80.         for (int i = 0; i < items.Length; i++) {
    81.             if (items[i] != null) {
    82.                 Vector3 itemPos = items[i].position;
    83.                 Vector3 topoint = itemPos - cpos;
    84.                 // ray from camera to item position
    85.                 Ray r = new Ray(itemPos, topoint);
    86.                 float enter = 0;
    87.                 p.Raycast(r, out enter);
    88.                 Vector3 posOnPlane = r.GetPoint(enter);
    89.                 dots.SetPosition(counter, posOnPlane);
    90.                 counter++;
    91.             }
    92.         }
    93.     }
    94. }
    95.  
    Example .unitypackage (script + scene)
    https://polyflow.xyz/content/temp/innovine-example/innovine-example.unitypackage
     
    Innovine likes this.
  10. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Can I get some help with this question too please?
     
  11. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Hi! I reported this bug in October, and it is present in non-beta versions of Unity also. I think you can fix it just by adding:
    UNITY_INITIALIZE_OUTPUT(v2fdot, o);
     
    Last edited: Jun 19, 2022
  12. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    There are some bugs in the placement and aspect of dots using the widthMode of WidthMode.WorldspaceXY.
    It displays the dot at an offset, depending on which rectIndex you use. And the aspect ratio is very wrong.

    Code (CSharp):
    1.     private Dots dots;
    2.     public Color Color = Color.yellow;
    3.     public DotsAtlas Atlas;
    4.     public float width = 0.1f;
    5.     public float height = 0.1f;
    6.     public int index = 1;
    7.  
    8.     public Vector3 pos = Vector3.zero;
    9.  
    10.     void Awake()
    11.     {
    12.         dots = new Dots(1);
    13.  
    14.         dots.colorMultiplier = Color;
    15.         dots.atlas = Atlas;
    16.         dots.widthMode = WidthMode.WorldspaceXY;
    17.  
    18.         dots.SetColor(0, Color);
    19.  
    20.     }
    21.  
    22.     void Update()
    23.     {
    24.         dots.SetRectIndex(0, index);
    25.         dots.SetSize(0, new Vector2(width, height));
    26.         dots.SetPosition(0, pos);
    27.         dots.Draw();
    28.     }
    upload_2022-6-20_19-47-18.png

    I expect the dot to be a circle, and I expect it to be drawn at the position (0, 0, 0).
    If i only change the rectIndex, the position of the dot will also change.
     
  13. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    I will be doing a demo of my game in two weeks and I really need a fix for this bug. Please @polyflow3d can you look into it ASAP.
     
  14. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    @polyflow3d Please can you do something about this bug ASAP...
     
  15. Nanomid

    Nanomid

    Joined:
    Nov 8, 2014
    Posts:
    15
    Not to be a jerk, but you do realize he lives (or lived) in Ukraine near the Donbas region? Staying healthy should be our first wish, IMO.
     
  16. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    That's unfortunate for a lot of people, but please keep politics out of it. As per the Unity Community Code Of Conduct, the list of forbidden things begins with: "1a. Discussions on political issues ".

    I don't think it is unreasonable to ask for support and a critical bug fix for a paid product. Plus, perhaps someone else who owns this and understands shader coding may be able to help in the meantime. It is really important to me.
     
    Last edited: Jul 20, 2022
  17. Nanomid

    Nanomid

    Joined:
    Nov 8, 2014
    Posts:
    15
    I didn't mention politics. You did.
     
  18. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    We aren't interested in any form of Ukraine / Russian / Political discussion on these forums now, or ever. Doing do will lead to infractions. So don't do it.

    Don't reply to this moderator post except for in PM if you must.
     
  19. Nanomid

    Nanomid

    Joined:
    Nov 8, 2014
    Posts:
    15
    Screen shot.
     
  20. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    A screenshot was already provided earlier. But here is another one and some better example code:

    Code (CSharp):
    1. public class LinefyDotsTest : MonoBehaviour
    2. {
    3.     private Dots dots;
    4.     [Range(0,48)] public int rectIndex;
    5.  
    6.     void Start()
    7.     {
    8.         dots = new Dots(1);
    9.         dots.widthMultiplier = 0.8f;
    10.         dots.transparent = true;
    11.         dots.colorMultiplier = Color.white;
    12.         dots.widthMode = WidthMode.WorldspaceXY;
    13.  
    14.         dots.SetColor(0, Color.white);
    15.         dots.SetPosition(0, Vector3.zero);
    16.         dots.SetSize(0, Vector2.one);
    17.         dots.SetRectIndex(0, rectIndex);
    18.     }
    19.  
    20.     private void OnValidate()
    21.     {
    22.         if (dots == null)
    23.             return;
    24.         dots.SetRectIndex(0, rectIndex);
    25.     }
    26.  
    27.     void Update()
    28.     {
    29.         dots.Draw(transform.localToWorldMatrix);
    30.     }
    31. }

    As you drag the rectIndex slider around, the dot should change rect index, but it should NOT move. Yet it does. The small sphere is located at (0,0,0) which is where I expect the dot to be.

    Screenshot 2022-08-02 200515.png Screenshot 2022-08-02 200528.png

    By dragging the rectIndex slider around in this example you can clearly see that the dot is drawn offset in X by some multiple of rectIndex%8 (the column position in the atlas), and in the Y by a constant plus a smaller multiple of rectIndex/8 (the row in the atlas).




    The problem is NOT limited to WorldspaceXY as I first thought. It also affects the other modes.
     
    Last edited: Aug 2, 2022
  21. demimonde

    demimonde

    Joined:
    May 3, 2021
    Posts:
    27
    Just bought this asset and it's really fantastic! However, for 2D it looks like it doesn't support sorting layers, which is a huge bummer. Is there any way to hack this in easily? This is so close to being exactly the tool I need, but without sorting layers I won't be able to use it in my current 2D project :(
     
  22. MagicMarten

    MagicMarten

    Joined:
    Jun 14, 2018
    Posts:
    1
    I am also interested in this, if anyone has an answer for that. Thanks
     
  23. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    @polyflow3d I reported this bug three and a half months ago and still no response. Can you please do something about it? I see you were logged into the forum last week. Please provide support for your asset.
     
  24. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297
    Innovine, I apologize for the delay in support. You have encountered a bug that attached patch fixes.

    Despite the fact that I was enlisted in the Ukrainian army and still serve in it, I continue to work on a new version of Linefy and provide support for it.
     

    Attached Files:

  25. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Excellent, much appreciated!!
    Good luck with your army service, kick ass.
     
    polyflow3d likes this.
  26. jonwah00

    jonwah00

    Joined:
    Jul 21, 2019
    Posts:
    36
    Hi, can you please help me with a problem I'm having with linefy? I am using polylines/text renderer in screen space, and when the camera moves, everything shakes (see attached gif)



    I'm using nearClipPlaneMatrix.screen (.gui also shakes); and calling Draw in LateUpdate - pretty much exactly the same as the polyline demo.
     
  27. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297

    I assume that camera moving controller script sets camera`s position (or Rotation) in LateUpdate but has greater value of execution order. Try to increase execution order of linefy-controlling script in order to it executed after camera script.
     
  28. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    Is it possible you are very far from the origin? Floating point precision errors cao look a bit like that
     
    polyflow3d likes this.
  29. jonwah00

    jonwah00

    Joined:
    Jul 21, 2019
    Posts:
    36
    Hi, my camera is about x 100, y 100, z -1000; is that what you would call very far? I understand Unity has issues when you're "far" from the origin but it's hard to find a decent reference on what far would be?
     
  30. jonwah00

    jonwah00

    Joined:
    Jul 21, 2019
    Posts:
    36
    Hi, thanks for your reply.. My camera script moves the camera location in Update; not LateUpdate..
     
  31. Sisay

    Sisay

    Joined:
    Dec 6, 2012
    Posts:
    57
    does it work on ps4?
     
  32. Innovine

    Innovine

    Joined:
    Aug 6, 2017
    Posts:
    522
    At the scale of one unity unit being one meter, the imprecision will be a few centimeters at 10km from the origin.
    So this probably not the problem in your case, unless your UI objects are millimeter sized.
     
  33. jonwah00

    jonwah00

    Joined:
    Jul 21, 2019
    Posts:
    36
    Thanks for the response, it doesn't seem to be the issue..


    I've also tried updating the script execution order to ensure my scripts (which use Linefy.Labels, Linefy.Polyline etc) are executed after NearClipPlaneMatrix (which has -10 value by default anyway?), but that also doesn't help..

    Any other ideas for things I can try?
     
  34. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    729
    Did you try updating the camera in late update?
     
  35. jonwah00

    jonwah00

    Joined:
    Jul 21, 2019
    Posts:
    36
    Yup, I've tried updating the camera in LateUpdate and tried ensuring that it runs AFTER NearClipPlaneMatrix each frame; no change.


    I have had some progress; this is where I'm at now - I changed pixelPerfect = false on my Linefy.Labels instances, and as you can see, it's worked on the x axis labels (running horizontally) but not the y axis labels (running vertically). The Linefy.Polyline instances (the coloured wavy line and green vertical line) seem absolutely rock solid; but SOME of the Linefy.Lines instances (the grid lines) are shaking.

    I've used the code in Graph.cs from the Linefy examples as a guide; that's what's doing the grid lines, labels etc. I've gone back and played with the graph example scene, moving the camera to try and see if I can replicate the issue but I can't (although there is a 1pixel shake around the outside of the screen).

    The major modifications I've made to it (the Graph.cs example code) is to try and cache as many variables as possible; all of the position calculations were being run every frame, which was a massive perf hit, so that's all pre-calculated and cached. I've tried copying my class and removing all of the caching, to see if that was the issue, and it wasn't.
     
  36. Wanwu314

    Wanwu314

    Joined:
    Feb 28, 2021
    Posts:
    10
    I am trying to add a mask to the linefy, I need to get the object position in the shader. However, I can't directly use v.vertex because it later will be changed by pixelToClip, could you please give me some idea of what is the object space pos looks like after process pixelToClip.

    This is what I want to achieve:
    (87) Clipping Effect Using Shaders In Unity3D | Speed Code - YouTube
     
    Last edited: Apr 1, 2023
    polyflow3d likes this.
  37. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297
    Is there any chance for me to get this scene? For now I have no idea about the cause of this jerking.
     
  38. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297
    You can achieve this effect in scripting level modify the position(width, color) of lines. Here is an example
     

    Attached Files:

  39. polyflow3d

    polyflow3d

    Joined:
    Oct 6, 2014
    Posts:
    297
    Lines slice by plane script
     

    Attached Files:

  40. Wanwu314

    Wanwu314

    Joined:
    Feb 28, 2021
    Posts:
    10
    Thank you for your reply, but this method only works on lines, is there any way to achieve this on polyline? If I split polylines into serval lines, there would have a problem with their corners.

    I'm still trying to achieve this with shader, but all I know so far is that shader changes the vertices to make face camera-oriented. If I still use the unprocessed vertices to get world space position
    o.worldPos= mul(unity_ObjectToWorld, v.vertex);
    , then there will be a few lines penetrating the plane, And I don't know why this problem become more serious on mobile.
     

    Attached Files:

    Last edited: Apr 11, 2023