@threlte/extras
<MeshLineMaterial>
Used in combination with <MeshLineGeometry>
to create a line formed of a strip of billboarded triangles, based on THREE.MeshLine.
<script lang="ts">
import { Canvas } from '@threlte/core'
import Scene from './Scene.svelte'
</script>
<div class="w-full h-full relative">
<Canvas>
<Scene />
</Canvas>
</div>
<script>
import { T, useFrame } from '@threlte/core'
import {
MeshLineMaterial,
MeshLineGeometry,
Grid,
OrbitControls,
useTexture
} from '@threlte/extras'
import { Vector3, CatmullRomCurve3, Color } from 'three'
// create a smooth curve from 4 points
const curve = new CatmullRomCurve3([
new Vector3(-3, 0, 0),
new Vector3(-1, 1, -1),
new Vector3(1, -1, 1),
new Vector3(3, 0, 0)
])
// convert curve to an array of 100 points
const points = curve.getPoints(100)
let width = 0.5
let dashOffset = 0
let color = new Color()
const orange = new Color('#fe3d00')
const purple = new Color('#9800fe')
useFrame((state, delta) => {
// every frame we:
// increase the dash offset
dashOffset += delta / 2
// transition between two colors
color.lerpColors(orange, purple, Math.sin(dashOffset * 2) / 2 + 0.5)
// shrink and grow the line width
width = Math.sin(dashOffset * 2) / 5 + 0.3
})
</script>
<T.Mesh
position.y={3}
scale={2}
>
<MeshLineGeometry {points} />
<MeshLineMaterial
{width}
{color}
dashArray={0.5}
dashRatio={0.5}
{dashOffset}
transparent
depthTest={false}
/>
</T.Mesh>
<T.PerspectiveCamera
makeDefault
on:create={({ ref }) => {
ref.position.set(10, 3, 10)
}}
>
<OrbitControls
autoRotate={true}
autoRotateSpeed={2}
enableDamping
target.y={2}
/>
</T.PerspectiveCamera>
<Grid
gridSize={[10, 10]}
cellColor={'#46536b'}
sectionThickness={0}
/>
Usage
This component works by taking a line geometry from <MeshLineGeometry>
and projecting and expanding the vertices in screen space.
Both <MeshLineMaterial>
and <MeshLineGeometry>
need belong to the same parent mesh.
Example
<script>
const points = [new Vector3(-5, 1, 0), new Vector3(0, 1, 0), new Vector3(5, 1, 0)]
</script>
<T.Mesh>
<MeshLineGeometry {points} />
<MeshLineMaterial
width={0.5}
color="#fe3d00"
/>
</T.Mesh>
Width and color
By default the line will be white and have a width of 1.
The width
property will use world units and scale correctly with other objects in your scene.
If you would like the line to be a fixed size regardless of distance from the camera you can set the attenuate
property to false
.
Opacity and dashes
Just like other materials in Three.js you need to set transparent
to true
for opacity to have any effect.
You must also set transparent
to true
for if you are using dashed lines.
You can use a combination of dashArray
, dashRatio
and dashOffset
to create dashed lines.
If you’re rendering transparent lines, dashed lines or lines with an alpha map you can avoid issues where the line overlaps itself by setting depthTest to false.
Alpha map
You can pass a texture to the alphaMap
property to use as an alpha mask along the length of the line, where black is invisible and black is visible.
In the example below we load a paint brush texture with the useTexture
hook.
<script lang="ts">
import { Canvas } from '@threlte/core'
import Scene from './Scene.svelte'
</script>
<div class="relative h-full w-full">
<Canvas>
<Scene />
</Canvas>
</div>
<script>
import { T, useFrame } from '@threlte/core'
import {
MeshLineMaterial,
MeshLineGeometry,
Grid,
OrbitControls,
useTexture
} from '@threlte/extras'
import { Vector3, CubicBezierCurve3, Color, DoubleSide } from 'three'
const texture = useTexture('/brush-texture.png')
// create a smooth bezier curve
const curve = new CubicBezierCurve3(
new Vector3(-5, 0, 0),
new Vector3(-5, 7, 0),
new Vector3(5, 7, 0),
new Vector3(5, 0, 0)
)
// convert curve to an array of 100 points
const points = curve.getPoints(100)
</script>
<T.Mesh rotation.z={-0.1}>
<MeshLineGeometry {points} />
{#await texture then alphaMap}
<MeshLineMaterial
width={1}
color={'#fe3d00'}
transparent
depthTest={false}
{alphaMap}
/>
{/await}
</T.Mesh>
{#await texture then map}
<T.Mesh
position.y={2}
scale={2}
>
<T.PlaneGeometry />
<T.MeshBasicMaterial {map} side={DoubleSide}/>
</T.Mesh>
{/await}
<T.PerspectiveCamera
makeDefault
on:create={({ ref }) => {
ref.position.set(0, 3, 10)
}}
>
<OrbitControls
autoRotateSpeed={2}
enableDamping
target.y={2}
/>
</T.PerspectiveCamera>
<Grid
gridSize={[10, 10]}
cellColor={'#46536b'}
sectionThickness={0}
/>
Component Signature
<MeshLineMaterial>
extends
<T.ShaderMaterial>
and supports all its props, slot props, bindings and events.