featured image
ThreeJS

How to Draw Lines and Edges

 - 

So many articles about ThreeJS are introductory. This is great when you’re just getting started, but I already understand what geometry and materials are and how they combine to meshes which are assembled into a scene tree along with some lights and the camera. I want to do more, but I don’t want to jump straight into some crazy Shader Toy madness. How about using shaders to do some simple things? How about drawing lines? How about simple uses for particles and noise? That’s what this series is about.

Lines

Lines are not as useful as you think. Because of the legacy of OpenGL you can draw lines but they will always be 1px thick (usually). That said, if you want to draw some lines you need line geometry, like an array of vertices, and then use a Line, LineLoop, or LineSegments to draw it like this:

mat = new THREE.LineBasicMaterial({color:0x0000FF})
mesh = new THREE.LineSegments(geo, mat)

The big question is where does your geometry come from. If you have some data you could just create an array of vertices. If instead you want to use an existing 3D model, or one of the geometry primitives like sphere or cube, then simply putting those in won’t do what you think it will do. It will draw the lines from point to point, but not what you think.

linesphere

What happened here is it randomly grabbed pairs of lines. Instead we want some new geometry of lines based on the original geometry. The EdgesGeometry class can do this for you.

ex:

const cube = new THREE.BoxBufferGeometry(1,1,1)
const geo = new THREE.EdgesGeometry(cube)

which will give you something like this:

linesphere04

You can combine a regular mesh with an edge mesh like this, to sort of draw the outline of the geometry on top of the geometry. It seems to work and I haven’t seen any depth fighting.

function setupScene() {
    const geo = new THREE.SphereGeometry(2)
    const mat = new THREE.MeshLambertMaterial({ color:0xff0000})
    mesh = new THREE.Mesh(geo,mat)
    mesh.position.z = -4
    scene.add(mesh)
    const edges = new THREE.EdgesGeometry(geo)
    mesh2 = new THREE.LineSegments(edges,
         new THREE.LineBasicMaterial({color:0x00ff00}))
    mesh2.position.z = -4
    scene.add(mesh2)
}

filledlinesphere

However, we still have the problem that we can’t really draw lines. They will always be thin. Probably not anti-aliased, and it will probably look different from machine to machine and driver to driver.

Drawing lines is just really hard. Here are a few ideas from Matt.

Next time we’ll look at faces.