MeshLine Class
The MeshLine class is the main interface for creating lines. It extends Mesh from three/webgpu and provides TSL-powered line rendering capabilities.
Quick Links:
- Common Patterns - Basic usage examples
- Advanced Patterns - GPU-driven positions, instancing, custom shaders
Constructor
new MeshLine(options?: MeshLineOptions)MeshLine supports both options object configuration and a fluent API with chainable methods for easy configuration.
Fluent API
The fluent API allow you to chain methods like the example bellow:
const line = new MeshLine()
.lines(positions)
.color(0xff0000)
.gradientColor(0x0000ff)
.lineWidth(2)
.opacity(0.8)See Common Patterns for more examples.
Geometry Configuration:
lines(lines: Float32Array | number[][], closed?: boolean | boolean[])- Set line(s) positions and optional close flagsegments(segments: number)- Set number of segments for auto-generated linesclosed(closed: boolean | boolean[])- Set whether to close the line loop
Appearance:
color(color: number | THREE.Color)- Set line colorlineWidth(lineWidth: number)- Set line widthwidthCallback(callback: (t: number) => number)- Set variable width functionsizeAttenuation(enable: boolean)- Enable/disable size attenuationgradientColor(color: number | THREE.Color)- Set gradient end colorvertexColors(colors: Float32Array | number[])- Set per-vertex RGB colorsopacity(opacity: number)- Set opacity level
Material Properties:
alphaTest(threshold: number)- Set alpha test thresholdtransparent(enable: boolean)- Enable/disable transparency, enable by default if opacity != 1 or alphaMapwireframe(enable: boolean)- Enable/disable wireframe mode
Textures:
map(texture: THREE.Texture)- Set diffuse texturealphaMap(texture: THREE.Texture)- Set alpha mask texturemapOffset(offset: THREE.Vector2)- Set texture UV offset
Dashes:
dash({ count: number, ratio?: number, offset?: number })- Configure dash pattern
Advanced:
join({ type: 'miter'|'bevel'|'round', limit?: number, quality?: 'standard'|'high' })- Control line joins; whentype: 'miter',limitandqualityapplydpr(ratio: number)- Set device pixel ratiofrustumCulled(enable: boolean)- Enable/disable frustum culling & geometry BoundingBox/boundingSphere creationverbose(enable: boolean)- Enable/disable verbose loggingrenderSize(width: number, height: number)- Set render resolutiongpuPositionNode(node: Fn)- Set GPU position calculation nodeusage(usage: THREE.Usage)- Set buffer usage hint for position/next/prev (if they exist)instances(count: number)- Enable instancing with specified countdynamic(enable: boolean)- Toggle dynamic geometry updates (usage hints)autoResize(target?: Window|HTMLElement)- Automatically update resolution on resize
Hook Functions:
The hook are used in the TSL Nodes in MeshLineNodeMaterial
positionFn(fn: Fn)- Set position modification hookpreviousFn(fn: Fn)- Set previous position hooknextFn(fn: Fn)- Set next position hookwidthFn(fn: Fn)- Set width modification hooknormalFn(fn: Fn)- Set normal modification hookcolorFn(fn: Fn)- Set color modification hookgradientFn(fn: Fn)- Set gradient modification hookopacityFn(fn: Fn)- Set opacity modification hookdashFn(fn: Fn)- Set dash modification hookuvFn(fn: Fn)- Set UV modification hookvertexFn(fn: Fn)- Set vertex modification hookfragmentColorFn(fn: Fn)- Set fragment color modification hookfragmentAlphaFn(fn: Fn)- Set fragment alpha modification hookdiscardFn(fn: Fn)- Set fragment discard condition hook
Attribute Control:
These controls give you control on which attributes are added to the geometry.
needsUV(enable: boolean)- Control UV attribute generationneedsWidth(enable: boolean)- Control width attribute generationneedsProgress(enable: boolean)- Control progress attribute generationneedsPrevious(enable: boolean)- Control previous position attribute generationneedsNext(enable: boolean)- Control next position attribute generationneedsSide(enable: boolean)- Control side attribute generationneedsVertexColor(enable: boolean)- Control vertex color attribute generation
Building:
build()- Finalize configuration and build the line (returns the instance).
Note: Call
build()to finalize the configuration & build the geometry and tsl nodes, or the line will auto-build on first render ( duringonBeforeRender).
Options Object Configuration
Alternatively, you can use the traditional options object approach:
Quick signature
interface MeshLineOptions {
// ***Geometry***
lines?: Float32Array | number[][] // Line points (required)
closed?: boolean | boolean[] // Close the loop(s)
// ***Appearance***
color?: number | THREE.Color
lineWidth?: number // Line width (default: 0.3)
widthCallback?: (t: number) => number // variable width modifier
sizeAttenuation?: boolean
gradientColor?: number | null // End-gradient colour
vertexColors?: Float32Array | number[] // Per-vertex RGB colors
// ***Textures***
map?: THREE.Texture | null
alphaMap?: THREE.Texture | null
mapOffset?: THREE.Vector2 | null
// ***Dashes***
dashCount?: number | null
dashRatio?: number | null
dashOffset?: number
// ***Rendering flags***
opacity?: number
alphaTest?: number
transparent?: boolean
wireframe?: boolean
frustumCulled?: boolean
// Device pixel ratio
dpr?: number
// ***Advanced / internal***
needsWidth?: boolean // generate attributes width
needsUV?: boolean
needsProgress?: boolean
needsPrevious?: boolean
needsNext?: boolean
needsSide?: boolean
needsVertexColor?: boolean // generate vertex color attribute
renderWidth?: number
renderHeight?: number
// Procedural GPU positions
gpuPositionNode?: Fn< number, THREE.Vector3 > | null
// Instancing
instanceCount?: number // Enable instancing with count
// Hook Functions (TSL Fn)
positionFn?: Fn | null
widthFn?: Fn | null
colorFn?: Fn | null
gradientFn?: Fn | null
opacityFn?: Fn | null
dashFn?: Fn | null
uvFn?: Fn | null
vertexFn?: Fn | null
fragmentColorFn?: Fn | null
fragmentAlphaFn?: Fn | null
discardFn?: Fn | null
// Debugging
verbose?: boolean
}MeshLineOptions
Geometry
lines(Float32Array | number[][]) — Required. The line points data. Can be an array of[x, y, z]coordinate arrays, or aFloat32Arraywith XYZ values. Default:new Float32Array([0,0,0,1,0,0]).
Procedural alternative: instead of supplying a
linesarray you can provide agpuPositionNodefunction (TSLFn). The node receives the per-vertexprogress(0→1) and must return avec3position. When set, the geometry sent to the GPU can be minimal – only its length matters so that theprogressattribute is generated.
closed(boolean | boolean[]) — Whether to close the line loop(s). Iftrue, connects the last point back to the first. For multiple lines, can be an array of booleans. Default:false.
Appearance
color(number | THREE.Color) — Base color of the line. Can be a hex number (0xff0000) orTHREE.Colorinstance. Default:0xffffff(white).lineWidth(number) — Width of the line. WhensizeAttenuationisfalse, this value is multiplied bydprfor screen-space rendering. Whentrue, it's scaled by distance. Default:0.3.widthCallback((t: number) => number | null) — A function that receives the line progress (t, from 0 to 1) and returns a width multiplier. Allows for variable line width. Default:null.sizeAttenuation(boolean) — Whether line width should scale with camera distance. Whenfalse, lines maintain constant pixel width regardless of distance. Default:true.gradientColor(number | null) — Optional gradient end color. When set, the line will smoothly transition fromcolortogradientColoralong its length. Default:null(no gradient).vertexColors(Float32Array | number[]) — Per-vertex RGB colors for individual point coloring. Should be a flat array of RGB values (0-1 range) with 3 values per vertex. When set, each point along the line can have its own color, multiplied with the basecolor. Best used withFloat32Arrayfor performance. Default:null(no vertex colors).
Textures
map(THREE.Texture | null) — Diffuse texture to apply along the line. The texture is mapped using UV coordinates generated along the line length. Default:null.alphaMap(THREE.Texture | null) — Alpha mask texture for transparency effects. Uses the blue channel of the texture for alpha values. Default:null.mapOffset(THREE.Vector2 | null) — UV offset for bothmapandalphaMaptextures. Allows shifting texture coordinates. Default:null(no offset).
Dashes
dashCount(number | null) — Number of dash cycles along the entire line length. When set, creates a dashed line pattern. Default:null(solid line).dashRatio(number | null) — Ratio of dash length to gap length (0 to 1). For example,0.5creates equal dash and gap lengths,0.7creates longer dashes with shorter gaps. Only works whendashCountis set. Default:null.dashOffset(number) — Offset into the dash cycle pattern. Animate this value to create moving dash effects. Default:0.
Rendering Flags
opacity(number) — Global opacity multiplier (0 to 1). Default:1(fully opaque).alphaTest(number) — Alpha threshold for fragment discard. Fragments with alpha below this value are discarded. Default:0.transparent(boolean) — Whether the material should be rendered with transparency. Auto-detected based on other settings if not explicitly set. Default:false.wireframe(boolean) — Render the line geometry as wireframe. Mainly useful for debugging. Default:false.frustumCulled(boolean) — Whether the line should be frustum culled by Three.js. Set tofalsefor lines that might extend outside the view. Default:true.
Device Pixel Ratio
dpr(number) — Device pixel ratio multiplier used for screen-spacelineWidth. Defaults towindow.devicePixelRatio.
Advanced / Internal
needsWidth(boolean) — Whether the line needs width information. Default:true.needsUV(boolean) — Whether the line needs UV coordinates. Default:true.needsProgress(boolean) — Whether the line needs a progress attribute. Default:true.needsPrevious(boolean) — Whether the line needs previous point information. Default:true.needsNext(boolean) — Whether the line needs next point information. Default:true.needsSide(boolean) — Whether the line needs side information. Default:true.renderWidth(number) — Width of the rendered line. Default:1024.renderHeight(number) — Height of the rendered line. Default:1024.verbose(boolean) — Whentruelogs to the console which buffer attributes are generated for the geometry. Useful for debugging option combinations. Default:false.
Instancing
instanceCount(number) — When set to a positive number, enables instanced rendering for the specified number of instances. Each instance renders the same line geometry but can have different transformations, colors, and other per-instance properties via custom attributes. Default:-1(instancing disabled).
Instance Attributes: Use
addInstanceAttribute(name, components)to create per-instance attributes andsetInstanceValue(name, index, value)to set data for specific instances. Instance attributes can be accessed in hook functions usingattribute(name, type).
Hook Functions
Hook functions allow custom TSL (Three.js Shading Language) code to modify various aspects of line rendering. All hooks are optional and receive relevant parameters for their processing stage:
positionFn(Fn | null) — Modify vertex positions. Receives(position, progress).widthFn(Fn | null) — Modify line width. Receives(width, progress, side).colorFn(Fn | null) — Modify vertex colors. Receives(color, progress, side).gradientFn(Fn | null) — Modify gradient factor. Receives(gradientFactor, side).opacityFn(Fn | null) — Modify opacity in fragment shader. Receives(alpha, progress, side).dashFn(Fn | null) — Modify dash pattern. Receives(cyclePosition, progress, side).uvFn(Fn | null) — Modify UV coordinates. Receives(uvCoords, progress, side).vertexFn(Fn | null) — Final vertex position modification. Receives(finalPosition, normal, progress, side).fragmentColorFn(Fn | null) — Final fragment color modification. Receives(color, uvCoords, progress, side).fragmentAlphaFn(Fn | null) — Final fragment alpha modification. Receives(alpha, uvCoords, progress, side).discardFn(Fn | null) — Custom discard condition. Receives(progress, side, uvCoords). Return truthy to discard fragment.
TSL Functions: Hook functions must be created using
Fn()fromthree/tsl. They run on the GPU for maximum performance and can access uniform values, attributes, and built-in variables liketimeandinstanceIndex.
Updating geometry efficiently
For lines controled by cpu and whose vertices change every frame (e.g. interactive trails) you can avoid rebuilding the full geometry by calling geometry.setPositions( positionsF32 ).positionsF32 must be the same length as the original lines array (and ideally the same Float32Array reused each frame). Only the position, previous and next buffers are updated in-place, so no new GPU buffers are created.
For efficient position updates, see Dynamic Updates in Common Patterns.
When verbose mode is enabled you'll see [MeshLine] positions updated via setPositions in the console.
Methods
Instance Management
addInstanceAttribute(name: string, components: number): InstancedBufferAttribute
Creates a new instanced buffer attribute with the specified name and component count. Returns the created InstancedBufferAttribute for direct manipulation if needed.
// Create a 3-component attribute for instance positions
const offsetAttr = line.addInstanceAttribute('instanceOffset', 3)
// Create a 1-component attribute for instance scale
const scaleAttr = line.addInstanceAttribute('instanceScale', 1)setInstanceValue(name: string, index: number, value: number | number[]): void
Sets the value for a specific instance at the given index. The value can be a single number (for 1-component attributes) or an array of numbers (for multi-component attributes).
// Set position for instance 0
line.setInstanceValue('instanceOffset', 0, [1, 2, 3])
// Set scale for instance 0
line.setInstanceValue('instanceScale', 0, 1.5)For advanced instancing examples, see:
- Basic Instancing for simple use cases
- GPU Instanced Circles for complex animated instances
Other Methods
resize(width?: number, height?: number): void
Updates the material's resolution uniform. Call this when the canvas size changes to maintain correct line width scaling.
dispose(): void
Cleans up GPU resources including geometry, material, and instance attributes. Call this when the line is no longer needed.