# WideLineRenderer

Class · category: Graphics

Source: https://github.com/playcanvas/engine/blob/f059dc005842f76e052cdf44d8370c8c7ec475ac/src/extras/renderers/wide-line-renderer.js#L550

Renders a collection of [WideLine](https://api.playcanvas.com/engine/classes/WideLine.md) objects using a single instanced draw call per
camera/layer pass. Lines can use different widths, colors, caps, joins and dash patterns while
remaining in the same batch, as these properties are stored in per-segment instance data.

Each [WideLine](https://api.playcanvas.com/engine/classes/WideLine.md) describes a connected polyline in world space. Its width can vary per point
and is interpreted as screen pixels or world units according to
[WideLineRenderer#widthUnits](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#widthunits). A line can belong to only one WideLineRenderer at a time. Use
[WideLineRenderer#add](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#add) and [WideLineRenderer#remove](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#remove) to transfer ownership without
changing the line data.

## Basic usage

The following example creates a three-point line with a color gradient, variable width and
rounded ends and joins:

```javascript
const renderer = new WideLineRenderer(app);
const line = new WideLine();

line.set(
    new Float32Array([
        -2, 0, 0,
         0, 1, 0,
         2, 0, 0
    ]),
    new Float32Array([
        1, 0, 0,
        1, 1, 0,
        0, 1, 1
    ]),
    new Float32Array([4, 12, 4])
);
line.cap = LINECAP_ROUND;
line.join = LINEJOIN_ROUND;
renderer.add(line);

// Release GPU resources and detach all lines when no longer needed.
app.on('destroy', () => renderer.destroy());
```

Point data can be updated using [WideLine#setPositions](https://api.playcanvas.com/engine/classes/WideLine.md#setpositions), [WideLine#setColors](https://api.playcanvas.com/engine/classes/WideLine.md#setcolors) and
[WideLine#setWidths](https://api.playcanvas.com/engine/classes/WideLine.md#setwidths). These methods preserve the point count and reuse the line's existing
storage. Use [WideLine#set](https://api.playcanvas.com/engine/classes/WideLine.md#set) when the point count needs to change.

## Performance

Each line segment is rendered as one GPU instance. All segments owned by this renderer are
submitted together, so adding more WideLine objects does not add draw calls. A renderer with
visible segments issues one draw call for each camera that renders its layer. Multiple renderers
therefore provide useful update isolation, but each adds another draw call per camera/layer
pass.

Changing any owned line marks the renderer dirty. Before the next render, instance data for all
of its lines is rebuilt and uploaded. For mixed workloads, place lines that rarely change in one
renderer and frequently updated lines in another. There is no static or dynamic mode; the
separation is achieved using two renderer instances. This prevents dynamic updates from
repeatedly rebuilding the static segment data:

```javascript
const staticLines = new WideLineRenderer(app);
const dynamicLines = new WideLineRenderer(app);

staticLines.add(roadNetwork); // Built and uploaded once.
dynamicLines.add(projectilePath); // Updated frequently.
```

Buffer [WideLineRenderer#capacity](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#capacity) is measured in segments and grows automatically as
needed. Setting it in advance can avoid GPU buffer reallocations when the expected maximum
segment count is known. [WideLineRenderer#clear](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#clear) removes the lines but retains this
capacity for reuse.

## Rendering behavior and limitations

- Rendering is opaque. Packed colors contain rgb values, the alpha component of a [Color](https://api.playcanvas.com/engine/classes/Color.md)
  is ignored and transparent lines are not supported.
- Widths use screen pixels by default. Set [WideLineRenderer#widthUnits](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#widthunits) to
  [LINEWIDTH_WORLD](https://api.playcanvas.com/engine/variables/LINEWIDTH_WORLD.md) for camera-facing ribbons measured in world units.
- [WideLineRenderer#depthTest](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#depthtest) and [WideLineRenderer#depthWrite](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#depthwrite) control interaction
  with the depth buffer. Both default to true.
- The renderer is added to the Immediate layer by default. Assign [WideLineRenderer#layer](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#layer)
  to render it in another layer.
- The batch is not frustum culled. Disable the renderer using [WideLineRenderer#enabled](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#enabled)
  when none of its lines need to be rendered.
- Call [WideLineRenderer#destroy](https://api.playcanvas.com/engine/classes/WideLineRenderer.md#destroy) to release the internal mesh, material and instance
  buffer. Detached lines remain usable and can be added to another renderer.

See the following examples for interactive styling and update demonstrations:

- [https://playcanvas.github.io/#/graphics/wide-line](https://playcanvas.github.io/#/graphics/wide-line)
- [https://playcanvas.github.io/#/graphics/wide-lines-styles](https://playcanvas.github.io/#/graphics/wide-lines-styles)
- [https://playcanvas.github.io/#/graphics/wide-lines-dynamic](https://playcanvas.github.io/#/graphics/wide-lines-dynamic)

## Constructors

### constructor

```ts
new WideLineRenderer(app: AppBase)
```

Creates a new wide line renderer.

**Parameters**

- `app` ([`AppBase`](https://api.playcanvas.com/engine/classes/AppBase.md)): The application.

## Accessors

### capacity

```ts
get capacity(): number
set capacity(value: number)
```

Gets the allocated instance capacity, measured in generated line segments.

### depthTest

```ts
get depthTest(): boolean
set depthTest(value: boolean)
```

Gets whether lines are tested against the depth buffer.

### depthWrite

```ts
get depthWrite(): boolean
set depthWrite(value: boolean)
```

Gets whether lines write to the depth buffer.

### enabled

```ts
get enabled(): boolean
set enabled(value: boolean)
```

Gets whether this renderer is visible.

### layer

```ts
get layer(): Layer
set layer(value: Layer)
```

Gets the layer containing the renderer's mesh instance.

### widthUnits

```ts
get widthUnits(): number
set widthUnits(value: number)
```

Gets the units used to interpret line widths.

## Methods

### add

```ts
add(line: WideLine): void
```

Adds a line to this renderer. A line can belong to only one renderer at a time.

**Parameters**

- `line` ([`WideLine`](https://api.playcanvas.com/engine/classes/WideLine.md)): The line to add.

### clear

```ts
clear(): void
```

Removes all lines. Allocated instance capacity is retained for reuse.

### destroy

```ts
destroy(): void
```

Releases all renderer-owned resources. Lines previously owned by this renderer remain
usable and can be added to another renderer.

### remove

```ts
remove(line: WideLine): boolean
```

Removes a line from this renderer without modifying its point data or style.

**Parameters**

- `line` ([`WideLine`](https://api.playcanvas.com/engine/classes/WideLine.md)): The line to remove.

**Returns** `boolean`: True if the line was owned by this renderer and was removed.
