Creating A GreasedLine

GreasedLine

GreasedLine is a special type of line which uses a regular mesh with triangles to display a line of any width. It incorporates custom shaders designed to ensure that the mesh always faces the camera resulting in consistent thickness from all perspectives. The shaders are provided using plugin material. You can use StandardMaterial or PBRMaterial with GreasedLine so you can use any property of the material to stylize your line. GreasedLine also features dashing, multicolored lines with sampling option, color blending options, variable width of both side of the line (upper, lower part), visibility (what percentage of the line is visible), points coordinates offsets, instance mode (you can add more lines to an instance and they will be drawn in one draw call), lazy mode. The values for these features are animatable. You can translate, rotate and scale the line as well because it's a mesh.

Create a GreasedLine

The easiest, prefered and recommended way to create a GreasedLine is to use the CreateGreasedLine function:

function CreateGreasedLine(name: string, options: GreasedLineMeshBuilderOptions, materialOptions?: Nullable<GreasedLineMaterialBuilderOptions>, scene?: Nullable<Scene>)

The simplest usage is:

const line = BABYLON.CreateGreasedLine("name", { points })
Basic usage Transforming a GreasedLine mesh

GreasedLineMeshBuilderOptions

You will find explanation of these options below this code snippet.

points: GreasedLinePoints;
widths?: number[];
widthDistribution?: GreasedLineMeshWidthDistribution;
instance?: GreasedLineMesh;
updatable?: boolean;
uvs?: number[];
lazy?: boolean;

points

Points of the line specified as x, y, z coordinates. All the points connected are called a line. The part of the line between two points is called a line segment in this documentation.

points can be type of number[], number[][], Vector3[], Vector3[][], Float32Array or Float32Array[].

If you want to draw only one contiguous line you can use 1D arrays or Float32Array. If you want to draw multiple lines you have to use 2D arrays or Float32Array[].

const points =
[
0, 0, 0,
1, 0, 0,
1, 1, 0
]
// x, y, z,
// x, y, z, ...
// is the same as
const points =
[
new BABYLON.Vector3(0,0,0)
new BABYLON.Vector3(1,0,0)
new BABYLON.Vector3(1,1,0)
]

It's a good habit to format your number coordinates for better readibility.

We recommend you to use the number or Float32Array objects if possible to avoid unnecessary creation of temporary Vector3 objects holding the points, mainly if you are creating the coordinates dynamically on the fly. The coordinates are converted to number[][] internally so number[] or number[][] are the fastest options.

To draw two or more at once lines you can define the points as:

const points = [
[ 0, 0, 0, 1, 0, 0],
[ 0, 1, 0, 1, 1, 0]
]

You can draw more lines at once by using the instance option. See the Instance mode example below.

You need to specify at least two points to draw a line, obviously.

Do not use sharp angle connected long lines because they can be distorted by perspective. Use smaller line segments. There are helper functions available in BABYLON.GreasedLineTools for that. See the GreasedLineTools section for more info. Another option is to create two lines and add them to one instance or you can add them as to separate lines like (this approach can cause little quirks where the lines 'connects' to each other when using dash mode - depending on your line width):

const points = [[
-10, 0, 0,
0, 10, 0
], [
0, 10, 0,
10, 0, 0
]]

Please not that points are not updatable unlike when using a LineMesh. You have to use the property offsets on the line instance to update the position of points. See below the Offsets section and the PG example Offsetting line vertices. However there are two public methods available on the line instance for manipulatind the points which can be useful when your are creating the line instance and the material instance separately (not recommended for most scenarios). Both of these functions will destroy the mesh and create a new one:

addPoints(points: number[][]) // ads points to the existing ones and recreates the mesh
setPoints(points: number[][]) // sets the points and recreates the mesh

If you are using the right handed coordinate system please create the lines after you switch the scene to it.

widths and widthDistribution

You can specify two width multiplier values for each point in your line. These values are multiplied with the width of the line to draw the resulting line. The first value specifies the width multiplier of the line below the line and the second above the line. These values are not normalized so if you use a value of 2, 2 the line will be twice the width at that point. There must be exactly the same count of width pair values as there are points.

The CreateGreasedLine function uses the function CompleteGreasedLineWidthTable to fill the missing values, if any. You can use the widthDistribution option to set the method used to automatically fill the widths table.

You can choose from these values:

enum GreasedLineMeshWidthDistribution {
WIDTH_DISTRIBUTION_NONE = 0,
WIDTH_DISTRIBUTION_REPEAT = 1,
WIDTH_DISTRIBUTION_EVEN = 2,
WIDTH_DISTRIBUTION_START = 3,
WIDTH_DISTRIBUTION_END = 4,
WIDTH_DISTRIBUTION_START_END = 5,
}

The default for this option is WIDTH_DISTRIBUTION_START.

Let's see an example:

const points = [0, 0, 0, 1, 0, 0]
const widths = [2, 2]
const line = BABYLON.CreateGreasedLine("line", { points, widths })
// the width table will be filled as [2, 2, 1, 1]

You can use the function CompleteGreasedLineWidthTable manually and set the widthDistribution to WIDTH_DISTRIBUTION_NONE. If you prepared the width table with the correct number of entries, set widthDistribution to WIDTH_DISTRIBUTION_NONE as well.

Please have a look at the API docs for more explanation about the width distribution modes.

You might wonder when you proceed reading to the materialOptions and you'll find the width option specified there and widths here. It's because the options objects contains all the mesh related options and width is used when creating the material, so it's material related.

Widths

instance

You can add lines to an existing line whenever you want. All you need to is to specify the instance option and set a GreasedLineMesh instance to it. Everytime you add a new line all the data needed to render the line will be recalculted and the buffers will be updated. If you are adding many lines to an instance, use the lazy option. Lines added to an instance are joined with the existing mesh. See the examples for code.

Instance mode

updatable

If you want to update your line mesh after it was created set this option to true when creating the line. This applies to offsets, segmentWidths and colorPointers. This option doesn't affect the line materials which can be updated any time. Set this value to false if you don't intend to update line mesh for more performance. If you are adding lines to an existing line instance you have to set this option on the line created the first.

uvs

You can set your custom UVs when creating the line.

lazy

You can disable recalculating line data and updating the buffers when adding a new line to a line instance by setting this option to true. This option is always used with the instance option specified. If you're done with adding new lines you just need to call line.updateLazy() to recalculate the data and update the buffers. See the examples for code.

Lazy mode

GreasedLineMaterialBuilderOptions

createAndAssignMaterial?: boolean;
width?: number;
sizeAttenuation?: boolean;
materialType?: GreasedLineMeshMaterialType;
color?: Color3;
colorMode?: GreasedLineMeshColorMode;
colors?: Color3[];
colorDistribution?: GreasedLineMeshColorDistribution;
colorDistributioType?: GreasedLineMeshColorDistributionType;
useColors?: boolean;
colorsSampling?: number;
useDash?: boolean;
dashCount?: number;
dashOffset?: number;
dashRatio?: number;
visibility?: number;
resolution?: Vector2;

createAndAssignMaterial

If set to true a new material will be created and a new material plugin will be attached to the material. The material will be set on the mesh. If the instance option is specified in the mesh options, no material will be created/assigned. If you omit GreasedLineMaterialBuilderOptions when calling CreateGreasedLine it behaves as if this option was set to true so it creates the material and the plugin. The default value is true. You can share the material between multiple lines so if you don't need a new material, set this to false to save resources and gain performance.

width

Line width in scene units unless sizeAttenuation is true. You can override the default value:

GreasedLinePluginMaterial.DEFAULT_WIDTH_ATTENUATED = 10
GreasedLinePluginMaterial.DEFAULT_WIDTH = 0.5

All lines created after setting this value and not providin a width option will use this value as the default one.

sizeAttenuation

If true then line will width be reduced.

materialType

Type of the material to use to render the line. Default is StandardMaterial. Currently you can choose from:

enum GreasedLineMeshMaterialType {
MATERIAL_TYPE_STANDARD = 0,
MATERIAL_TYPE_PBR = 1,
MATERIAL_TYPE_SIMPLE = 2
}

The first two materials are implemented using material plugins. The simple material is based on a shader material. It is super fast but does support only plain colors without lighting.

color

Color of the line. Applies to all line segments. Defaults to White. You can change the default color to any other color.

BABYLON.GreasedLinePluginMaterial.DEFAULT_COLOR = BABYLON.Color3.Green()

colorMode

Color mode of the line. Applies to all line segments. The pixel color from the material shader will be modified with the value of color using the colorMode. The default mode is GreasedLineMeshColorMode.SET. It means it will set the color regardless the color from the material shader. To be more precise it will set the color to the exact value and doesn't care about the color information from the material (texures, lighting, ...)

You can choose from and the names are selfexplanatory:

enum GreasedLineMeshColorMode {
COLOR_MODE_SET = 0,
COLOR_MODE_ADD = 1,
COLOR_MODE_MULTIPLY = 2,
}

Please not a difference: MATERIAL_TYPE_SIMPLE mixes the color and colors of the greased line material. MATERIAL_TYPE_STANDARD and MATERIAL_TYPE_PBR mixes the color from the base material with the color or the colors of the greased line material.

Simple material in multiply color mode

colors and colorDistribution

An array of colors of the line segments. Maximum number of colors supported for one line instance depends on the maximum texture width (we use 1D textures here for maximum performance) your GPU can support. Minimum for all WebGL systems is 4k. On most modern desktop GPUs it is 16k. Each color in the array represents a line segment color. There must be exactly the same amount of colors in the array as there are line segments in the line.

The CreateGreasedLine function uses the function CompleteGreasedLineColorTable to fill the missing values, if any. You can use the colorDistribution option to set the method used to automatically fill the colors table.

You can choose from these values:

enum GreasedLineMeshColorDistribution {
COLOR_DISTRIBUTION_NONE = 0,
COLOR_DISTRIBUTION_REPEAT = 1,
COLOR_DISTRIBUTION_EVEN = 2,
COLOR_DISTRIBUTION_START = 3,
COLOR_DISTRIBUTION_END = 4,
COLOR_DISTRIBUTION_START_END = 5,
}

The default for this option is COLOR_MODE_START.

Let'see an example (you will end up with a half red half white line)

const points = [0, 0, 0, 1, 0, 0, 2, 0, 0]
const colors = [BABYLON.Color3.Red()]
const line = BABYLON.CreateGreasedLine("line", { points }, { colors })
// the color table will be filled as [red, white] - white is the default

The colors are used only when the option useColors is set to true and you doesn't set the color option. There is one exception, see the documentation for the useColors option below.

The color blending of the colors depends on colorMode option.

Line colors

colorDistributionType

The method used to distribute the colors along the line. You can use segment distribution when each segment will use one color from the color table. Or you can use line distribution when the colors are distributed evenly along the line ignoring the segments.

Color distribution type Line colors using your own texture Animating line colors using your own texture Setting color pointers manually

colorsSampling

Sampling type of the colors texture. Defaults to NEAREST_NEAREST. The line segment will be distinctly colored. If you use for example LINEAR_LINEAR you'll get a smooth color gradient.

Colors sampling

useColors

If true, colors are used, otherwise they're ignored.

There is a scenario when you need to set useColors to true and set the color option as well. Look at the PG:

Adding differently colored lines to an instance

useDash

If true, dashing is used.

Dashing

dashCount

Number of dashes in the line. If you add more lines, all of them will use this dash count and they are not treated as one line.

dashRatio

Length of the dash. 0 to 1. 0.5 means half empty, half drawn.

dashOffset

Offset of the dashes along the line. 0 to 1. Normalized value.

visibility

Sets the line length visibility. Normalized value. 0 - 0% of the line will be visible. 1 - 100% of the line will be visible.

Visibility

resolution

Rendering resolution. There may be special occasions when you want to change the resolution. In most cases do not set this value.

GreasedLine materials

GreasedLine uses StandardMaterial or PBRMaterial or ShaderMaterial (MATERIAL_TYPE_SIMPLE) as the base material for rendering. It also uses a GreasedLinePluginMaterial which plugs into the base material and provides the additional features of GreasedLine.

If you want to alter the properties of the material you need to use line.material but if you want to change the GreasedLine specific material properties you need to do it on the line.greasedMaterial object. All three materials implements the IGreasedLineMaterial interface:

/**
* Interface which defines the available methods for a GreasedLineMaterial
*/
export interface IGreasedLineMaterial {
/**
* Normalized value of how much of the line will be visible
* 0 - 0% of the line will be visible
* 1 - 100% of the line will be visible
*/
visibility: number;
/**
* Line base width. At each point the line width is calculated by widths[pointIndex] * width
*/
width: number;
/**
* Turns on/off dash mode
*/
useDash: boolean;
/**
* @see GreasedLinePluginMaterial.setDashCount
* Number of dashes in the line.
* Defaults to 1.
*/
dashCount: number;
/**
* Dash offset
*/
dashOffset: number;
/**
* Length of the dash. 0 to 1. 0.5 means half empty, half drawn.
*/
dashRatio: number;
/**
* Whether to use the colors option to colorize the line
*/
useColors: boolean;
/**
* The mixing mode of the color paramater. Default value is GreasedLineMeshColorMode.SET. MATERIAL_TYPE_SIMPLE supports only the default value/mode.
* @see GreasedLineMeshColorMode
*/
colorMode: GreasedLineMeshColorMode;
/**
* Colors of the line segments.
* Defaults to empty.
*/
colors: Nullable<Color3[]>;
/**
* If false then width units = scene units. If true then line will width be reduced.
* Defaults to false.
*/
sizeAttenuation: boolean;
/**
* Color of the line. Applies to all line segments.
* Defaults to White.
* MATERIAL_TYPE_STANDARD and MATERIAL_TYPE_PBR material's shaders will get recompiled if there was no color set and you set a color or when there was a color set and you set it to null.
*/
color: Nullable<Color3>;
/**
* The method used to distribute the colors along the line.
* You can use segment distribution when each segment will use on color from the color table.
* Or you can use line distribution when the colors are distributed evenly along the line ignoring the segments.
*/
colorsDistributionType: GreasedLineMeshColorDistributionType;
/**
* Defaults to engine.getRenderWidth() and engine.getRenderHeight()
* Rendering resolution
*/
resolution: Vector2;
/**
* Allows to change the color without marking the material dirty.
* MATERIAL_TYPE_STANDARD and MATERIAL_TYPE_PBR material's shaders will get recompiled if there was no color set and you set a color or when there was a color set and you set it to null. Use the flag to not to recompile immediately.
* @param value the color
* @param doNotMarkDirty the flag
*/
setColor(value: Nullable<Color3>, doNotMarkDirty?: boolean): void;
/**
*
* @param colors colors array
* @param lazy if true the colors texture will not be updated
* @param forceNewTexture forces to create a new colors texture
*/
setColors(colors: Nullable<Color3[]>, lazy: boolean, forceNewTexture?: boolean): void;
/**
* Creates and sets the colors texture from the colors array which was created in lazy mode
*/
updateLazy(): void;
}

All other properties must be defined when creating the line.

As you can see in the comment of the color public property, the shader gets recompiled if there are specific changes of this property. A real life scenario: You might want to draw textured lines. On a specific event you want colorize the texture. In this case create the line with color set to Color3.White() and set the colorMode to GreasedLineColorMode.COLOR_MODE_MULTIPLY. The result will be the same as not setting a color. However now you can change the color to for example rgb(0.5, 0.5, 0.5) to dim the texture colors without shader recompilation. This doesn't apply to MATERIAL_TYPE_SIMPLE because this material supports only GreasedLineColorMode.COLOR_MODE_SET so there will be no shader recompilation upon changes of the color property at all.

Materials can be shared between line instances. If you create a line a the other should have the same material options then create the other line(s) by setting it's material option createAndAssign material to false and simply set the material:

const points1 = [-1, 0, 0, 1, 0, 0]
const line1 = BABYLON.CreateGreasedLine("line1", { points: points1 })
const points2 = [-1, 1, 0, 1, 1, 0]
const line2 = BABYLON.CreateGreasedLine("line2", { points: points2 }, { createAndAssignMaterial: false })
line2.material = line1.material

Examples

The best way to show the possibilities of GreasedLine is to go trough the following examples.

Basic code snippets with StandardMaterial

Line with no material settings, default width, default color

const points = [-1, 0, 0, 1, 0, 0]
const line = BABYLON.CreateGreasedLine("line", { points })

Lines with no material settings, default width, default color

const points = [[-1, 0, 0, 1, 0, 0], [-1, 1, 0, 1, 1, 0]]
const lines = BABYLON.CreateGreasedLine("lines", { points })

Line with a color specified

const points = [-1, 0, 0, 1, 0, 0]
const line = BABYLON.CreateGreasedLine("line", { points }, { color: BABYLON.Color3.Red() })

Line with a width specified

const points = [-1, 0, 0, 1, 0, 0]
const line = BABYLON.CreateGreasedLine("line", { points }, { width: 0.5 })

Line with multiple colors

const points = [-1, 0, 0, 1, 0, 0]
const colors = [BABYLON.Color3.Red(), BABYLON.Color3.Yellow()]
const line = BABYLON.CreateGreasedLine("line", { points }, { useColors: true, colors })

Line with multiple widths

const points = [-1, 0, 0, -0.5, 0, 0, 0, 0, 0, 0.5, 0, 0, 1, 0, 0]
const widths = [1, 1, 2, 2, 3, 3, 2, 2]
const line = BABYLON.CreateGreaseLine("line", { points }, [ widths ])

Instance mode

const points = [-1, 0, 0, 1, 0, 0]
const line = BABYLON.CreateGreasedLine("line", { points })
const points2 = [-1, 1, 0, 1, 1, 0]
BABYLON.CreateGreasedLine("line", { instance: line, points: points2 })

Lazy mode

const points = [-1, 0, 0, 1, 0, 0]
const line = BABYLON.CreateGreasedLine("line", { lazy: true, points })
const points2 = [-1, 1, 0, 1, 1, 0]
BABYLON.CreateGreasedLine("line", { instance: line, lazy: true, points: points2 })
const points3 = [-1, -1, 0, 1, -1, 0]
BABYLON.CreateGreasedLine("line", { instance: line, lazy: true, points: points3 })
line.updateLazy()

Dashed line

const points = [-1, 0, 0, 1, 0, 0]
const line = BABYLON.CreateGreasedLine("line", { points }, { useDash: true, dashCount: 4, dashRatio: 0.5})

Line visibility

const points = [-1, 0, 0, 1, 0, 0]
const line = BABYLON.CreateGreasedLine("line", { points }, { visibility: 0.5 })

Offsets

You can offset the vertices of the line. Keep in mind that there are 2 vertices per point and the line must be updatable. If your line disappears after calling this function it means you've provided not enough offsets. There is a function BABYLON.GreasedLineTools.GetPointsCountInfo(points: number[][]): { total: number; counts: number[] } which will tell you the exact counts. Just pass you line points option to this function.

const points = [-1, 0, 0, 1, 0, 0]
const line = BABYLON.CreateGreasedLine("line", { points, updatable: true })
const offsets = [
-0.3, -0.3, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0
]
line.offsets = offsets
Offsetting line vertices Offsetting line segments Modifying points positions

Adding/setting points to an existing GreasedLine instance

You can add points to an existing GreasedLine instance. The width table is extended automatically to match the vertices count and the new widths are set to 1. You have replace these values manually after the points were added if needed. You can do it by setting the values on the line.widths array.

The color table, if useColors is true must be extended manually. Please pay attention to the code in the PG and the comments how to correctly extend the color table.

The line must be created with the updatable: true option.

Have a look at the PG called Adding and setting points on an existing instance at the end of the page.

Line transformations

const points = [-1, 0, 0, 1, 0, 0]
const line = BABYLON.CreateGreasedLine("line", { points })
line.position.x = 2
line.rotation.z = Math.PI / 2
line.scaling = new BABYLON.Vector3(2, 2, 2)

Drawing arcs

const f = new BABYLON.Vector3(-0.5 + Math.random(), -0.5 + Math.random(), -0.5 + Math.random()).scale(20);
const s = new BABYLON.Vector3(-0.5 + Math.random(), -0.5 + Math.random(), -0.5 + Math.random()).scale(20);
const t = new BABYLON.Vector3(-0.5 + Math.random(), -0.5 + Math.random(), -0.5 + Math.random()).scale(20);
const arc = BABYLON.Curve3.ArcThru3Points(f, s, t);
const arcLine = BABYLON.CreateGreasedLine("arc", { points: arc.getPoints() })

Line with texture

const points1 = [-6, 0, 0, 6, 0, 0]
const line1 = BABYLON.CreateGreasedLine(
"line1",
{ points: points1 },
{ width: 1, colorMode: BABYLON.GreasedLineMeshColorMode.COLOR_MODE_MULTIPLY }
)
const texture = new BABYLON.Texture("/textures/amiga.jpg", scene)
texture.uScale = 10
line1.material.emissiveTexture = texture

The default color is white and the default colorMode is BABYLON.GreasedLineMeshColorMode.COLOR_MODE_SET so you need to set colorMode to BABYLON.GreasedLineMeshColorMode.COLOR_MODE_MULTIPLY to render the texture visible or you can remove the color by setting it's value to null if you don't want to do color blending at all. Setting the color from null to a value or setting from a value to null will recompile the shader.

const points1 = [-6, 0, 0, 6, 0, 0]
const line1 = BABYLON.CreateGreasedLine("line1", { points: points1 }, { width: 1 })
line1.greasedLineMaterial.color = null
const texture = new BABYLON.Texture("/textures/amiga.jpg", scene)
texture.uScale = 10
line1.material.emissiveTexture = texture

Setting line color using it's material

You have to set a colorMode option or set the color to null. Setting the color from null to a value or setting from a value to null will recompile the shader.

const points1 = [-6, 0, 0, 6, 0, 0]
const line1 = BABYLON.CreateGreasedLine("line1", { points: points1 }, { width: 1 })
line1.greasedLineMaterial.color = null
line1.material.emissiveColor = BABYLON.Color3.Red()

Glowing line

You have to set a colorMode option or set the color to null. Setting the color from null to a value or setting from a value to null will recompile the shader.

const points1 = [-6, 0, 0, 6, 0, 0]
const line1 = BABYLON.CreateGreasedLine("line1", { points: points1 }, { width: 1 })
line1.greasedLineMaterial.color = null
line1.material.emissiveColor = BABYLON.Color3.Red()
const gl = new BABYLON.GlowLayer("glow", scene, {
blurKernelSize: 32,
})
gl.intensity = 1.8;
gl.referenceMeshToUseItsOwnMaterial(line1)

Line using PBRMaterial

All you have to do is set the materialType to BABYLON.GreasedLineMeshMaterialType.MATERIAL_TYPE_PBR and set the colorMode to BABYLON.GreasedLineMeshColorMode.COLOR_MODE_MULTIPLY. Do not set the color to null as it was the case with StandardMaterial unless you set the base color of the line another way, for example by setting a texture on PBRMaterial.

const points = [-1, 0, 0, 1, 0, 0]
const line = BABYLON.CreateGreasedLine("line",
{ points },
{
materialType: BABYLON.GreasedLineMeshMaterialType.MATERIAL_TYPE_PBR,
colorMode: BABYLON.GreasedLineMeshColorMode.COLOR_MODE_MULTIPLY,
}
)
const pbrMaterial = line.material
// set your PBR material properties here

Text using GreasedLine

You can draw text with Greased Line as well.

const fontData = await (await fetch("https://assets.babylonjs.com/fonts/Droid Sans_Regular.json")).json();
const points = BABYLON.GreasedLineTools.GetPointsFromText(
"BabylonJS",
16, // size
16, // resolution
fontData // typeface.js font
)
const textLines = BABYLON.CreateGreasedLine("textLines", { points })

Read more about the GetPointsFromText function below and check out the example PG.

GreasedLineTools

The GreasedLineTools contains useful helper functions which will help you to easily handle common tasks when using GreasedLine. Refer to the API for details.

Meshes to lines

You can easily draw a wireframe of a mesh like this:

const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", { segments: 32, diameter: 2 }, scene);
const sphereLines = BABYLON.CreateGreasedLine(
"sphereLines",
{ points: BABYLON.GreasedLineTools.MeshesToLines([sphere]) }
)

You can use a predicate as the second parameter of this function to modify the line points returned from this function. The predicate is called once for a face (once for every 3rd indice).

predicate?: (
p1: Vector3,
p2: Vector3,
p3: Vector3,
indiceIndex: number,
vertexIndex: number,
mesh: AbstractMesh,
meshIndex: number,
vertices: FloatArray,
indices: IndicesArray
) => Vector3[]
const predicate = (p1, p2, p3, ix, vx) => {
if (vx % 4 === 0) {
return [p1, p2, p3, p1]
}
return false
}
const points = BABYLON.GreasedLineTools.MeshesToLines([sphere], predicate)

Convert number[] to Vector3[] and vice versa

You will often face situations when you need to convert your point coordinates mainly when using GreasedLineTools functions. There are two helper functions for that:

BABYLON.GreasedLineTools.ToVector3Array(points: number[])
BABYLON.GreasedLineTools.ToNumberArray(array: Vector3[])

Getting the count of points in your line instance

You will face certain tasks such creating color textures, offset buffers, etc. and you will need to know how many points is the line instance created from. Mainly if you use the functions below which will divide and segmentize your lines you'll easily lost tracking of the exact counts. You get the total number of points and number of points in each line in the line instance.

BABYLON.GreasedLineTools.GetPointsCountInfo(points: number[][]): { total: number; counts: number[] }

is here to help.

Dividing a line to smaller segments

You may want to divide your line to smaller pieces (to segments) for example for assigning different colors to the segments or setting different width on the segment or manipulating the offset of that smaller segment.

const pointsOriginal = BABYLON.GreasedLineTools.ToVector3Array([0, 0, 0, 1, 0, 0])
const points = BABYLON.GreasedLineTools.SegmentizeLineBySegmentLength(pointsOriginal, 0.25)
const points2 = BABYLON.GreasedLineTools.SegmentizeLineBySegmentCount(pointsOriginal, 4)

The line will be divided into 4 pieces because the line length is 1 and we asked for 0.25 long segments when using the first function or you can provide the number segments using the second function. Check the playgrounds for real life examples.

Finding the last visible position on the line when using the visibility option

The visibility option allows you to render only part of the line. You can use this option to reveal your line by incrementing it's value. Remember, the value of this option must be normalized so it must be between 0 and 1. For example you may want to display a marker where the line ends. You can use the BABYLON.GreasedLineTools.GetPositionOnLineByVisibility(lineSegments: { point1: Vector3; point2: Vector3; length: number }[], lineLength: number, visbility: number, localSpace = false) function for this. Examine the example Playground how to deal with this function.

Getting points from text and a typeface.js font - the GetPointsFromText function

You can draw texts using GreasedLine. See the example code snippet above and the PG below.

GreasedLineTools.GetPointsFromText(text: string, size: number, resolution: number, fontData: IFontData, z = 0, includeInner = true): number[][]

The size is the height of the text in BabylonJS units. Keep the resolution as low as possible without loosing details. Start at low values as 4 and go up to 32-64 (or you can use 1 to get cool low resolution vector font). fontData is the same object you would use with BABYLON.MeshBuilder.CreateText. You can generate yout typeface.js font here.

Other functions

There are other useful functions like getting points for drawing a circle/oval, an arc, drawing arrows, getting line length, etc. Check the source code, the API and/or the playgrounds.

As an overall rule always cache your parameters when calling functions. These functions located in GreasedLineTools may be CPU intensive so avoid using them in the render loop or cache as much as possible. For example convert your number coordinates to Vector3 coordinates once and store the result. Get the line length only once and buffer the value. Etc...

Picking and intersections

You can use the findAllIntersections(ray) function on the a GreasedLineMesh object to find the intersections of the ray and the line. You can finetune the intersection sensitivity by altering the value of the public property intersectionTreshold.

Example playgrounds

Vertex colors Picking & intersection Adding and setting points on an existing instance Glowing lines Arrows Curves Drawing text GetPositionOnLineByVisibility tool function example Cloning Serialization and parsing Using PBR material Using PBR material with a texture PBR sphere demo PBR sphere demo with a mesh to line predicate Mesh to 'opaque' lines example with PBR

Coming next