@lume/three-meshline v4.0.5
@lume/three-meshline
Provides a Mesh-based replacement for THREE.Line from
Three.js, allowing line thicknesses of any size
(THREE.Line is limited to 1 pixel width), and other features.
Note This is forked from
three.meshline, as that project has been dormant. The version of this starts at 2.0 because it modernizes the code base in ways that make it a breaking change, and removes deprecated features.
Instead of using GL_LINE, it uses a strip of triangles billboarded. Some examples:
Demos
How to use
- Include script
- Create an array of 3D coordinates
- Create a
MeshLineGeometryand assign the points - Create a
MeshLineMaterialto style the line points - Create a
MeshLinerendering object given theMeshLineGeometryandMeshLineMaterial
Install
With self-hosted dependencies installed locally:
First install @lume/three-meshline:
npm i @lume/three-meshlineAdd the importmap to your HTML if you are using native JavaScript modules (if you have a build step handling your modules, you'd skip this):
<script src="/node_modules/@lume/three-meshline/importmap.js"></script>If your browser doesn't support importmaps natively yet, you can load an importmap polyfill then embed the importmap manually in your HTML like so:
<script defer src="https://ga.jspm.io/npm:es-module-shims@1.6.3/dist/es-module-shims.js"></script>
<script src="/node_modules/@lume/three-meshline/importmap.js"></script>Finally import APIs into your JavaScript code:
import {MeshLine, MeshLineGeometry, MeshLineMaterial} from '@lume/three-meshline'Create an array of 3D coordinates
First, create the list of numbers that will define the 3D points for the line.
const points = []
for (let j = 0; j < Math.PI; j += (2 * Math.PI) / 100) {
points.push(Math.cos(j), Math.sin(j), 0)
}Create a MeshLineGeometry and assign the points
Once you have that, you can create a new MeshLineGeometry, and call
.setPoints() passing the list of points.
const geometry = new MeshLineGeometry()
geometry.setPoints(points)Note: .setPoints 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
geometry.setPoints(points, p => 2) // makes width 2 * lineWidth
geometry.setPoints(points, p => 1 - p) // makes width taper from the beginning
geometry.setPoints(points, p => 1 - (1 - p)) // makes width taper from the end
geometry.setPoints(points, p => 2 + Math.sin(50 * p)) // makes width sinusoidalCreate a MeshLineMaterial
A MeshLine needs a MeshLineMaterial:
const material = new MeshLineMaterial(options)By default it's a white material with line width 1 unit.
MeshLineMaterial accepts options to control the appereance of the MeshLine:
resolution-THREE.Vector2specifying the canvas size (REQUIRED) (default:new Vector2(1, 1))map- aTHREE.Textureto paint along the line (requiresuseMapset to true) (default:null)useMap- tells the material to usemap(false- solid color,trueuse texture) (defaultfalse)alphaMap- aTHREE.Textureto use as alpha along the line (requiresuseAlphaMapset to true) (default: 'null')useAlphaMap- tells the material to usealphaMap(false- no alpha,truealpha from texture) (default:false)repeat-THREE.Vector2to define the texture tiling (applies tomapandalphaMap) (default:new Vector2(1, 1))color-THREE.Colorto paint the line width, or tint the texture with (default:new Color('white'))opacity- alpha value from0to1(requirestransparentset totrue) (default:1)alphaTest- cutoff value from0to1(default:0)dashArray- the length and space between dashes. (0- no dash) (default:0)dashOffset- defines the location where the dash will begin. Ideal to animate the line. (default:0)dashRatio- defines the ratio between that is visible or not (0- more visible,1- more invisible) (default:0.5)useDash- whether to use dashes or not. SettingdashArrayto a non-zero value automatically sets this totrue. (false- no dashes,true- dashes) (default:
true)
- dashes) (default:
sizeAttenuation- makes the line width constant regardless distance (1 unit is 1px on screen) (false- attenuate,true- don't attenuate) (default:true)lineWidth- width of the line (ifsizeAttenuationistrue, the value is in world units; othwerwise it is in screen pixels) (default:1)visibility- A number from0to1denoting the portion of the line that is visible, starting from the end (0.5means half of the line is visible,0means the whole line is invisible) (default:1)
If you're rendering transparent lines or using a texture with alpha map, you may
consider setting depthTest to false, transparent to true and blending
to an appropriate blending mode, or use alphaTest.
Use MeshLineGeometry and MeshLineMaterial to create a MeshLine
Finally, we create a mesh and add it to the scene:
const line = new MeshLine(geometry, material)
scene.add(line)Note that MeshLine extends from THREE.Mesh and adds raycast support:
const raycaster = new THREE.Raycaster()
// Use raycaster as usual:
raycaster.intersectObject(line)Declarative use
react-three-fiber
MeshLine can be used declaritively. This is how it would look like in
react-three-fiber. You can try it
live
here.
import {extend, Canvas} from 'react-three-fiber'
import {MeshLine, MeshLineMaterial, MeshLineRaycast} from '@lume/three-meshline'
extend({MeshLine, MeshLineGeometry, MeshLineMaterial})
function Line({points, width, color}) {
return (
<Canvas>
<meshLine>
<meshLineGeometry attach="geometry" points={points} />
<meshLineMaterial
attach="material"
transparent
depthTest={false}
lineWidth={width}
color={color}
dashArray={0.05}
dashRatio={0.95}
/>
</meshLine>
</Canvas>
)
}Dynamic line widths can be set along each point using the widthCallback prop.
<meshLineGeometry attach="geometry" points={points} widthCallback={pointWidth => pointWidth * Math.random()} />TODO
- Better miters
- Faster setPoints() method
- Size attenuation when using OrthographicCamera
- Support for vertex colors (
geometry.vertexColors) - global script for people still using global script tags for a global THREE variable
Support
Tested successfully on
- Chrome OSX, Windows, Android
- Firefox OSX, Windows, Anroid
- Safari OSX, iOS
References
License
MIT licensed