a blog by Bartek Drozdz

3 ways to draw 3D lines in Unity3D

Just as I was thinking about an interesting demo to play with drawing functions in Unity3D, Mrdoob published his Harmony drawing tool made with HTML5/Canvas. It looks really cool, so I though how about doing this in 3D? I only had to figure out how to draw lines.

I did some research and below I present 3 different solutions. You can grab the source of the examples discussed below here.

Drawing lines with Line Renderer [demo]

When it comes to lines, the first thing you’ll bump into in the Unity3D API is the Line Renderer component. As the name suggests, it is used to draw lines so it seems the right tool for the job. Lines in this case are defined by 2 or more points (segments), a material and a width.

It has an important limitation: the line must be continuous. So if you need two lines, you need two renderers. The other problem is that the Line Renderer acts very strangely when new points are added dynamically. The width of the line does not seem to render correctly. It’s either buggy or just wasn’t designed for such use. Because of these limitations I had to create a separate Line Renderer for each tiny bit of line I’m drawing.

It was easy to implement, but not very fast since I end up spawning lots of GameObjects each with a LineRenderer attached. It seems to be the only option if you don’t have Unity3D Pro though.

Drawing lines as a mesh using Graphics [demo]

The Graphics class allows to draw a mesh directly without the overhead of creating game objects and components to hold it. It runs much faster than Line Renderer, but you need to create the lines yourself. This is a bit more difficult but also gives you total control of the lines – their color, material, width and orientation.

Since meshes are composed of surfaces rather than lines or points, in 3D space a line is best rendered as a very thin quad. A quad is described with 4 vertices, and usually you’ll only have the start and end points and a width. Based on this data you can compute a line like this:

Vector3 normal = Vector3.Cross(start, end); Vector3 side = Vector3.Cross(normal, end-start); side.Normalize(); Vector3 a = start + side * (lineWidth / 2); Vector3 b = start + side * (lineWidth / -2); Vector3 c = end + side * (lineWidth / 2); Vector3 d = end + side * (lineWidth / -2);

First, you get the normal of the plane on which both start and end vectors lie. This will be the plane on which the line-quad will located. The cross product of the normal and of the difference between end and start vectors gives you the side vector (the “thin” side of the quad). You need to normalize it to make it a unit vector. Finally calculate all 4 points of the rectangle by adding the side vector multiplied by half width to both start and end points in both directions. In the source code all this happens in MakeQuad and AddLine methods, so take a look in there.

It wasn’t easy to implement, but once I was there it runs pretty fast.

Direct drawing with GL [demo]

No fast is fast enough! Instead of leaving this topic and live happily with the Graphics solution, I kept searching for something even better. And I found the GL class. GL is used to “issue rendering commands similar to OpenGL’s immediate mode”. This sounds like fast, doesn’t it? It is!

Being much easier to implement that the Graphics solution it is a clear winner for me, the only drawback being that you don’t have much control over the appearance of the lines. You can’t set a width and perspective does not apply (i.e. lines that are far behind look exactly the same as those that are close to the camera).

Conclusion

For massive & dynamic line drawing LineRenderer is not the best solution, but it is the only one available in Unity free version. It can surely be useful to draw limited amounts of static lines and this is probably what it was made for. If you do have Unity3D Pro, the solution with Graphics is reasonable and very flexible but if it is performance you’re after choose GL.

  • elkraneo on March 15th, 2010

    mentioned in my blog…really interesting job, thx!!
    http://www.elkraneo.com/2010/03/15/3-ways-to-draw-3d-lines-in-unity3d-everyday-flash/
    :)

  • michael on March 15th, 2010

    Bartek — why not start a Unity blog or a build out something more expansive than “every day flash?”

    I come here because of the flash work you’ve done — which is the point of this particular blog, but all you’ve talked about for a long time is Unity. I certainly would not ask you to post more flash if you do not wish to, but it’s repeatedly disappointing for me and probably very many others to see new posts (exciting) not about flash.

  • bartek drozdz on March 15th, 2010

    @michael Thanks for this comment, I never looked at things this way! It’s true, there wasn’t much Flash on this blog lately. I guess I owe you and other readers an explanation. At first I wanted to put it in this comment, but it seems like it deserves a separate post. It will be coming soon.

  • Seb Lee-Delisle on March 15th, 2010

    Bartek, keep it up. I for one am enjoying your posts. If the name of your blog is misleading or restrictive then change it. But for me at least, it’s important to follow all web technologies and Unity is very interesting indeed. This is your blog and you should document what you’re learning. :-)

    cheers

    Seb

  • elkraneo on March 15th, 2010

    Seb says it…not relevant the name, i found your blog and your vision inspiring….

  • samBrown on March 15th, 2010

    Barteck, I enjoy the posts as well – even the ‘non-flash’ ones :)

  • Dominic Mercier on March 15th, 2010

    Barteck, I both enjoy your Flash and Unity posts.
    Even i have never use Unity, i feel a know a little bit about it just by reading your very useful post.

    This is your blog and you can write about what you want. Your flash tips are so incredible for the community. It will be a big loss for the community if you stop blogging about Flash.

    Keep the good work.

  • Michał Wróblewski on March 15th, 2010

    I find your post very inspiring. The effect matters, not the technique you used. BTW. If you make something in Unity there’s a challenge to make it with ActionScript :) This 3d drawing tool is the best example.
    Many thanks for your inspiring work!

  • Michael Walsh on March 15th, 2010

    Flash, Unity, whatever you are experimenting with through your blog posts one thing remains the same, they are always very inspirational and encouraging.

    Looking forward to your next post Bartek, whatever it may be.

  • vitaLee on March 15th, 2010

    i do enjoy your unity posts and like Dominic mentioned i feel like i’m getting familiar with unity by reading them.
    keep up the good work Bartek ;) .

  • Devin Reimer on March 16th, 2010

    Keep up the good work. I quite enjoy the Unity stuff. I to am finding my own blog is shifting away from Flash and over to Unity. I think it is important not to lock yourself into one thing just do what your passionate about.
    I’m with Seb if changing your blog url would help, go for it. You can always redirect this url to the new one. :)

  • Mark on March 16th, 2010

    Wonderful! I personally am glad that you’ve jumped into Unity3d land. I too have gone from being a flash dev (founder of flashkit.com even) into a unity game developer. Its just sometimes fun and exciting to try something new thats fun, and fast.

    Unity certainly has its quirks and issues ( lack of a click drag selection tool springs to mind) but the goodies it has are pretty sweet. Its just fun.

    And I wanted to say an extra special thanks for the sources to this demo :D Ive only just started playing with custom meshes and this has helped me out as well…. I reckon I could use this technique to make skids……

    The GR version works well on the iphone too! I’m excited about whatever new goodies you come up with next.

  • Einar Öberg on March 16th, 2010

    Great blogs is about inspiration. And this is truly one of them. I’m standing on the tippingpoint of trying out Unity myself, so keep them coming. It’s also great with this experimental approach, beyond game development.

  • shaman4d on March 16th, 2010

    Could you please describe what base algorithm of drawing when line draw near other line?

  • [...] http://www.everydayflash.com/b……n-unity3d/ { no comment } :| { Tags: note unity3d } [...]

  • Weekly Digest for March 16th on March 16th, 2010

    [...] 3 ways to draw 3D lines in Unity3D – Everyday Flash [...]

  • George Profenza on March 16th, 2010

    Wow, nice toy! MrDoob’s Harmony is awesome, but the 3d thingy has a nice feel to it too. If you could save a jpeg, it would be great.
    It has a nice potter’s wheel touch to it and somwhat similar to Rhonda(rhondaforever.org) a bit.

    I played with the demos a bit (at work, so in a hurry) and used the rotation thingy as a crotch, here are a few ‘sketches’:

    lr: http://www.screencast.com/t/ZTI2Zjg3Y2E
    gr: http://www.screencast.com/t/YzkzZWMwMD
    drawing: http://www.screencast.com/t/NDMwNTkyN2Q

    The last one looks a bit medieval/grotesque, but interesting.

    Anyway, cool toys, keep it up.

    Looking forward for LFPUG btw :)

  • [...] Confira aqui. [...]

  • Dessiner dans Unity on March 24th, 2010

    [...] site Everydayflash a transposé une méthode de flash permettant de dessiner dans Unity. L’intérêt est de [...]

  • mike on July 21st, 2010

    Using GR method is almost perfect.
    But!
    Now when lines are thin everything is ok. But when lines are wider, there is perspective segmet distortion (based on camera pos). It’ll be nice to have segments rotated towards camera. Like particles billboarding effect or native Line Renderer.

    LR problem is that LR align segments to camera but keeps segments connected. that provide unexpected twists and texture flips.

    Can you update the GR code?
    Please.
    Im not math guru but seems to me, you are.
    Thanks.

  • Once on December 8th, 2010

    3.1 把脚本OBJ.cs改为继承MonoBehaviour后,然后再根据提示稍微改下是可以用的。

  • Giulian Drimba on December 22nd, 2010

    Many thanks for this! Exactly what I need :D

  • tomekkie on March 5th, 2011

    Your unity3d files, those embedded in full browser mode, display right in Firefox and Google Chrome, but there is a problem with them in Internet Explorer 8, they do not display. Is it a matter of UnityObject.js file? I am wondering how to properly embedd in full browser mode. Would be grateful for any comments. Thanks,

    Tomek

  • EricH on July 5th, 2011

    Feel free to remove this if it’s too much like advertising, but I’d recommend Vectrosity for line drawing if you don’t have Unity Pro: http://starscenesoftware.com/vectrosity.html Even if you do have Pro, I’d still recommend it. ;) It can actually be significantly faster than GL.LINES, because you only have to update lines that change. Static lines are only the cost of having a mesh on the screen. With GL.LINES, you have to update all lines every frame, regardless of whether they’re actually changing or not, or else they won’t render. I optimized Vectrosity as much as I could manage, so even if you are updating all lines every frame, it’s only about 2.5X slower than GL.LINES, but it’s far more flexible. Among other things you have complete control over line width of every segment.

  • bartek drozdz on July 9th, 2011

    @EricH vectrosity looks interesting! Based on the experience I’m having now with WebGL, where everything is on a much lower level, I know that drawing lines as quads (option 1 and 2 in the above post) will always be slower than drawing using gl native line mode. In WebGL (following opengl) you can actually set the width of the lines that way, but Unity3d does not expose this functionality in the GL object.

    UPDATE: I was wrong about thick lines in WebGL, apparently for that you need to draw quads as well: http://sonargame.com/blog/2011/06/19/thick-lines-in-webgl/

  • Dave on March 21st, 2012

    Hi, just dropping in to say thanks for posting this, nice elegant solution to drawing lines. A great follow-up would be how to stick the quads/tris together so you don’t get any ‘gaps’ between them in thick lines whose angle changes ;) (Working on that now myself)

  • Parandham on April 10th, 2012

    Shall i use this code in my project.is it free.

  • Brad on August 9th, 2012

    Thanks a lot :) Will be using this a lot

  • Jay on August 31st, 2012

    Thanks for researching and posting this info, was a huge help

  • Dmitry on November 7th, 2012

    Since from unity 4 we will have a GL/Graphics classes avalaible in free version, we can use all these 3 ways to draw lines.
    Proofes:
    1. http://unity3d.com/unity/licenses
    2. http://forum.unity3d.com/threads/140798-A-minor-point-that-is-quite-awesome-with-Unity-4

    It’s great, thanks for post!

Post a comment