ryanking1809 / threejs-meshline

Mesh replacement for THREE.Line
MIT License
59 stars 9 forks source link

This fork has now been merged into THREE.meshline 1.3.0

THREE.meshline code will work exactly the same, however, meshline.setVertices and meshline.vertices have been renamed to meshline.setPoints and meshline.points.



Click examples above to view the code and the examples found at THREE.meshline will work with this fork.

npm install threejs-meshline

threejs-meshline is a replacement for THREE.Line, it allows you to create lines with varable widths. It is a fork of Jaume Sanchez Elias THREE.meshline as the repo no longer appears to be maintained.

How to use

Fetch imports

import { MeshLine, MeshLineMaterial, MeshLineRaycast } from 'threejs-meshline'

Create and populate a geometry

First, create the list of vertices that will define the line. MeshLine accepts an array of vertices.

const vertices = []
for (let j = 0; j < Math.PI; j += (2 * Math.PI) / 100)
  vertices.push(new THREE.Vector3(Math.cos(j), Math.sin(j), 0))

Create a MeshLine and set the vertices

Once you have that, you can create a new MeshLine, and call .setVertices() passing the vertices.

const line = new MeshLine()
line.setVertices(vertices)

Note: .setVertices accepts a second parameter, which is a function to define the width in each point along the line. By default that value is 1, making the line width 1 * lineWidth in the material.

// p is a decimal percentage of the number of points
// ie. point 200 of 250 points, p = 0.8
line.setVertices(geometry, p => 2) // makes width 2 * lineWidth
line.setVertices(geometry, p => 1 - p) // makes width taper
line.setVertices(geometry, p => 2 + Math.sin(50 * p)) // makes width sinusoidal

Create a MeshLineMaterial

A MeshLine needs a MeshLineMaterial:

const material = new MeshLineMaterial(OPTIONS)

By default it's a white material of width 1 unit.

MeshLineMaterial has several attributes to control the appereance of the MeshLine:

If you're rendering transparent lines or using a texture with alpha map, you should set depthTest to false, transparent to true and blending to an appropriate blending mode, or use alphaTest.

Use MeshLine and MeshLineMaterial to create a THREE.Mesh

Finally, we create a mesh and add it to the scene:

const mesh = new THREE.Mesh(line, material)
scene.add(mesh)

You can optionally add raycast support with the following.

mesh.raycast = MeshLineRaycast

Declarative use

threejs-meshline has getters and setters that make declarative usage a little easier. This is how it would look like in react/react-three-fiber. You can try it live here.

import { extend, Canvas } from 'react-three-fiber'
import { MeshLine, MeshLineMaterial, MeshLineRaycast } from 'threejs-meshline'

extend({ MeshLine, MeshLineMaterial })

function Line({ vertices, width, color }) {
  return (
    <Canvas>
      <mesh raycast={MeshLineRaycast}>
        <meshLine attach="geometry" vertices={vertices} />
        <meshLineMaterial
          attach="material"
          transparent
          depthTest={false}
          lineWidth={width}
          color={color}
          dashArray={0.05}
          dashRatio={0.95}
        />
      </mesh>
    </Canvas>
  )
}