Draw several high-density line in 2D

Hi guys, I need to draw at least 4 lines on screen, each line is made of 6000 point (Following image). I have tried Vectrosity, FastLineRenderer, Unity’s LineRenderer, and so on, nothing good enough so far. The purpose of this is to draw a real-time signal graph to visualize data. Do you have any suggestion? I thought it could be good to change color of specific pixels, however, due to lack of enough knowledge, I don’t know how to achieve this.

and you tried the trailRenderer right?

what about them is not good enough, where do you have issues?

Actually no, I haven’t tried TrailRenderer, I’ll go for it now.
“Not good enough” means data flow passes drawing process behind, I mean I get real-time data but I don’t get real-time drawing, usually drawing process gets up to several minutes behind!

There is a problem with TrailRenderer as is with LineRenderer. At peaks of signal, there are breaks for large change of signal, it cannot handle changes smoothly. Take a look at picture:
2664614--188009--Untitled - 1.png

Edit: I changed “Min Vertex Distance” to 0 and problem solved so far.

Another Edit: Event with previous Edit, real-time data makes something like this:

All the signal is made with the same pattern, but you can see because of rate of data, TrailRenderer cannon catch data and misses several points.I tried this in these methods: FixedUpdate, Update, OnGUI and I got same result.

Do you need the line to be a single object? Could you create a series of duplicates (quads or hexagons) like bread crumbs giving the illusion of a solid line?
2665040--188046--upload_2016-6-5_11-10-22.pngalpha 0.5 for demonstration
careful with batches

the real-time speed you are going for might actually be the issue; in that regard I have no solution.

Why do you need 6000 samples? There aren’t even that many pixels across a 4K display.

As for your issue of trying to update 6000 points, getting that data from the CPU to the GPU is going to get expensive both to calculate and to transfer. Usually you want to try to find a simpler form for the data to transfer even if it means more processing on the CPU. Assuming the entire line is something that’s not changing every frame, only scrolling to the side with the ends being updated and removed you could break up each line into multiple parts so you’re only updating the front portion and maybe just letting the end scroll off screen and recycle it to the front. The other parts are effectively static and you’re moving the gameObject rather than updating the line mesh each frame.

For the line breaks, that’s a little harder. You need to be using a surprisingly advanced line renderer to handle those well, or as suggested above just a lot more points. Both cases gets really slow fast.

I would actually suggest using a shader to do the line drawing, either as a pixel shader or using a vertex shader to offset a pre tessellated mesh. Again I would say split it up into parts, but you could send the points over as a simple 1 dimensional texture.

I solved my problem by drawing on a sprite, it works great and very fast!

There’s nothing at all about Vectrosity that would do that, just FYI. If you update the line data and call Draw, the line is updated that frame. It’s not actually possible for it to be delayed. Same goes for Unity’s LineRenderer, for that matter.

–Eric

Actually it happens! When it comes to draw 4 lines of 6k samples, it drops frame rate down to 20 fps. As a result, incoming data got queued, waiting to be rendered. Finally I have a huge amount of waiting-to-be-rendered data.

Maybe on a very old/slow device; on a reasonable computer you’d be getting at least 100-200fps for the line drawing for that amount of points, tested with Vectrosity anyway (not sure about LineRenderer).

–Eric

Can you post your code? Maybe there is an issue with my code.

Test code just to have something to draw every frame:

#pragma strict
import Vectrosity;
import System.Collections.Generic;

private var lines : VectorLine[];
private var points : List.<List.<Vector2> >;

function Start () {
    lines = new VectorLine[4];
    points = new List.<List.<Vector2> >();
    for (var i = 0; i < 4; i++) {
        points.Add (new List.<Vector2>(6000));
        lines[i] = new VectorLine("Test", points[i], 2.0, LineType.Continuous);
    }
    lines[0].color = Color.red;
    lines[1].color = Color.green;
    lines[2].color = Color.cyan;
}

function Update () {
    for (var i = 0; i < 4; i++) {
        for (var j = 0; j < 6000; j++) {
            points[i][j] = Vector2(j*.1, Random.Range(0, 100) + i*100);
        }
        lines[i].Draw();
    }
}

Results in:

2667283--188189--Screen Shot 2016-06-07 at 3.56.49 AM.png

So the line drawing + canvas rendering is a bit under 5ms, which means 200+fps. (And this is in the editor with the profiler on; a build will be faster.)

–Eric

Yeah, you’re right, it works about 200fps. I’m gonna test it again on my app. I’ll post the results asap. BTW, thank you.

With a few optimization, it works smoothly on an Intel i3 + Intel HD (my target platform). Thank you guys, specially Eric5h5 :wink: