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.

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.

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:

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.

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.

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.

@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.

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. :-)

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!

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. :)

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.

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.

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’:

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.

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,

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.

@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.

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)

it’s to do with rendering, you will notice it is a fast render. You’re supposed to have multiple components grouped to a transform for multiple lines

Tim commented on February 19th, 2016

Thanks! This was super useful. But for some reason, when using the Graphics option, when I use this for my project, I can only see the lines drawn in the scene view. The camera can’t see them. But the camera can see the lines drawn in the demo project. Any insight as to why this may be would be much appreciated.

Viren Patel commented on October 26th, 2016

“Note that in almost all cases using Graphics.DrawMesh or CommandBuffer is more efficient than using immediate mode drawing.” You missed this line in the documentation. Oops.

Post a comment

everyday3d is a blog run by Bartek Drozdz about web development with a focus on realtime 3d graphics. It's been around since 2007. First, it focused on Flash (remember?) then moved over to Unity3d, WebGL and eventually - Virtual Reality and 360°.

I hope you enjoy the articles and demos posted here. Most of what I write about, I thaught myself from good books. Here's a few I would recommend if you want to deepen your knowledge of creative coding, math and realtime graphics.