# MeshInstance

Class · category: Graphics

Source: https://github.com/playcanvas/engine/blob/f059dc005842f76e052cdf44d8370c8c7ec475ac/src/scene/mesh-instance.js#L285

An instance of a [Mesh](https://api.playcanvas.com/engine/classes/Mesh.md). A single mesh can be referenced by many mesh instances that can
have different transforms and materials.

A mesh instance is created from a [Mesh](https://api.playcanvas.com/engine/classes/Mesh.md), a [Material](https://api.playcanvas.com/engine/classes/Material.md) and the [GraphNode](https://api.playcanvas.com/engine/classes/GraphNode.md)
whose world transform places it, and it is drawn only once it belongs to a [Layer](https://api.playcanvas.com/engine/classes/Layer.md).
Components such as [RenderComponent](https://api.playcanvas.com/engine/classes/RenderComponent.md) create mesh instances from their assets and add them
to the layers in their `layers` list. A mesh instance you construct yourself is placed either
by assigning it to [RenderComponent#meshInstances](https://api.playcanvas.com/engine/classes/RenderComponent.md#meshinstances) or by adding it to a layer directly
with [Layer#addMeshInstances](https://api.playcanvas.com/engine/classes/Layer.md#addmeshinstances).

Per-instance rendering state lives here rather than on the shared mesh or material:
[visible](https://api.playcanvas.com/engine/classes/MeshInstance.md#visible), [castShadow](https://api.playcanvas.com/engine/classes/MeshInstance.md#castshadow) and `receiveShadow`, [cull](https://api.playcanvas.com/engine/classes/MeshInstance.md#cull) for frustum culling,
[drawOrder](https://api.playcanvas.com/engine/classes/MeshInstance.md#draworder) for manual sorting, and [setParameter](https://api.playcanvas.com/engine/classes/MeshInstance.md#setparameter) for shader uniforms that override
the material's. [aabb](https://api.playcanvas.com/engine/classes/MeshInstance.md#aabb) is the world-space bounds derived from the mesh bounds and the
node's transform, and can be assigned to override it.

### Instancing

Hardware instancing lets the GPU draw many copies of the same geometry with a single draw call.
Use [setInstancing](https://api.playcanvas.com/engine/classes/MeshInstance.md#setinstancing) to attach a vertex buffer that holds per-instance data
(for example a mat4 world-matrix for every instance). Set [instancingCount](https://api.playcanvas.com/engine/classes/MeshInstance.md#instancingcount)
to control how many instances are rendered. Passing `null` to [setInstancing](https://api.playcanvas.com/engine/classes/MeshInstance.md#setinstancing)
disables instancing once again.

```javascript
// vb is a vertex buffer with one 4×4 matrix per instance
meshInstance.setInstancing(vb);
meshInstance.instancingCount = numInstances;
```

The default matrix format, [VertexFormat.getDefaultInstancingFormat](https://api.playcanvas.com/engine/classes/VertexFormat.md#getdefaultinstancingformat), occupies the
attribute locations of `TEXCOORD6` and `TEXCOORD7`. A material sampling those UV sets on an
instanced mesh needs a custom instancing vertex format on other attributes, as shown by the
instancing-custom example.

**Examples**

- [graphics/instancing-basic](https://playcanvas.github.io/#graphics/instancing-basic)
- [graphics/instancing-custom](https://playcanvas.github.io/#graphics/instancing-custom)

### GPU-Driven Indirect Rendering (WebGPU Only)

Instead of issuing draw calls from the CPU, parameters are written into a GPU
storage buffer and executed via indirect draw commands. Allocate one or more slots with
`GraphicsDevice.getIndirectDrawSlot(count)`, then bind the mesh instance to those slots:

```javascript
const slot = app.graphicsDevice.getIndirectDrawSlot(count);
meshInstance.setIndirect(null, slot, count); // first arg can be a CameraComponent or null
```

**Example**

- [compute/indirect-draw](https://playcanvas.github.io/#compute/indirect-draw)

### Multi-draw

Multi-draw lets the engine submit multiple sub-draws with a single API call. On WebGL2 this maps
to the `WEBGL_multi_draw` extension; on WebGPU, to indirect multi-draw. Use [setMultiDraw](https://api.playcanvas.com/engine/classes/MeshInstance.md#setmultidraw)
to allocate a [DrawCommands](https://api.playcanvas.com/engine/classes/DrawCommands.md) container, fill it with sub-draws using
[DrawCommands#add](https://api.playcanvas.com/engine/classes/DrawCommands.md#add) and finalize with [DrawCommands#update](https://api.playcanvas.com/engine/classes/DrawCommands.md#update) whenever the data changes.

Support: [GraphicsDevice#supportsMultiDraw](https://api.playcanvas.com/engine/classes/GraphicsDevice.md#supportsmultidraw) is true on WebGPU and commonly true on WebGL2
(high coverage). When not supported, the engine can still render by issuing a fast internal loop
of single draws using the multi-draw data.

```javascript
// two indexed sub-draws from a single mesh
const cmd = meshInstance.setMultiDraw(null, 2);
cmd.add(0, 36, 1, 0);
cmd.add(1, 60, 1, 36);
cmd.update(2);
```

### Precedence

When draw commands (indirect or multi-draw, see [setIndirect](https://api.playcanvas.com/engine/classes/MeshInstance.md#setindirect) and [setMultiDraw](https://api.playcanvas.com/engine/classes/MeshInstance.md#setmultidraw))
are bound, they are the source of truth for rendering: the number of draws and the per-draw
instance counts come from the draw commands, and [instancingCount](https://api.playcanvas.com/engine/classes/MeshInstance.md#instancingcount) is ignored. In this
case setting [instancingCount](https://api.playcanvas.com/engine/classes/MeshInstance.md#instancingcount) to 0 does not skip rendering. [instancingCount](https://api.playcanvas.com/engine/classes/MeshInstance.md#instancingcount) only
takes effect for plain hardware instancing, when no draw commands are bound.

## Constructors

### constructor

```ts
new MeshInstance(mesh: Mesh, material: Material, node?: GraphNode)
```

Create a new MeshInstance instance.

**Parameters**

- `mesh` ([`Mesh`](https://api.playcanvas.com/engine/classes/Mesh.md)): The graphics mesh to instance.
- `material` ([`Material`](https://api.playcanvas.com/engine/classes/Material.md)): The material to use for this mesh instance.
- `node` ([`GraphNode`](https://api.playcanvas.com/engine/classes/GraphNode.md), optional, default `null`): The graph node defining the transform for this instance. This
  parameter is optional when used with [RenderComponent](https://api.playcanvas.com/engine/classes/RenderComponent.md) and will use the node the
  component is attached to.

**Example**

```ts
// Create a mesh instance pointing to a 1x1x1 'cube' mesh
const mesh = Mesh.fromGeometry(app.graphicsDevice, new BoxGeometry());
const material = new StandardMaterial();

const meshInstance = new MeshInstance(mesh, material);

const entity = new Entity();
entity.addComponent('render', {
    meshInstances: [meshInstance]
});

// Add the entity to the scene hierarchy
this.app.scene.root.addChild(entity);
```

## Properties

### castShadow

```ts
castShadow: boolean = false
```

Enable shadow casting for this mesh instance. Use this property to enable/disable shadow
casting without overhead of removing from scene. Note that this property does not add the
mesh instance to appropriate list of shadow casters on a [Layer](https://api.playcanvas.com/engine/classes/Layer.md), but allows mesh to
be skipped from shadow casting while it is in the list already. Defaults to false.

### cull

```ts
cull: boolean = true
```

Controls whether the mesh instance can be culled by frustum culling (see
[CameraComponent#frustumCulling](https://api.playcanvas.com/engine/classes/CameraComponent.md#frustumculling)). Defaults to true.

### drawOrder

```ts
drawOrder: number = 0
```

Determines the rendering order of mesh instances. Only used when mesh instances are added to
a [Layer](https://api.playcanvas.com/engine/classes/Layer.md) with [Layer#opaqueSortMode](https://api.playcanvas.com/engine/classes/Layer.md#opaquesortmode) or [Layer#transparentSortMode](https://api.playcanvas.com/engine/classes/Layer.md#transparentsortmode)
(depending on the material) set to [SORTMODE_MANUAL](https://api.playcanvas.com/engine/variables/SORTMODE_MANUAL.md).

### shaderPassMask

```ts
shaderPassMask: number = 0xFFFFFFFF
```

A bitmask controlling which shader passes this mesh instance is rendered in. Bit N
corresponds to the shader pass with index N: the built-in forward pass is
[SHADER_FORWARD](https://api.playcanvas.com/engine/variables/SHADER_FORWARD.md), and indices for custom shader passes are obtained from
[CameraComponent#setShaderPass](https://api.playcanvas.com/engine/classes/CameraComponent.md#setshaderpass). Defaults to `0xFFFFFFFF` (all passes). For example,
clearing the forward pass bit keeps the mesh in the other passes (such as the camera depth
prepass that feeds Depth of Field) while making it invisible in the rendered color image.

**Example**

```ts
// clear the forward (color) pass bit, leaving all other pass bits set: the mesh is no longer
// drawn in the color image, but still takes part in the other passes (such as the prepass)
meshInstance.shaderPassMask &= ~(1 << SHADER_FORWARD);
```

**Example**

```ts
// set the forward (color) pass bit, leaving all other pass bits unchanged
meshInstance.shaderPassMask |= (1 << SHADER_FORWARD);
```

**Example**

```ts
// exclude the mesh from a custom shader pass set up on the camera (see
// CameraComponent#setShaderPass), leaving all other pass bits set
const customPass = cameraComponent.setShaderPass('custom_rendering');
meshInstance.shaderPassMask &= ~(1 << customPass);
```

**Example**

```ts
// test whether the forward (color) pass bit is set
const forwardBitSet = (meshInstance.shaderPassMask & (1 << SHADER_FORWARD)) !== 0;
```

**Example**

```ts
// set every pass bit (the default value)
meshInstance.shaderPassMask = 0xFFFFFFFF;
```

### shadowCascadeMask

```ts
shadowCascadeMask: number = SHADOW_CASCADE_ALL
```

Specifies a bitmask that controls which shadow cascades a mesh instance contributes
to when rendered with a [LIGHTTYPE_DIRECTIONAL](https://api.playcanvas.com/engine/variables/LIGHTTYPE_DIRECTIONAL.md) light source.
This setting is only effective if the [castShadow](https://api.playcanvas.com/engine/classes/MeshInstance.md#castshadow) property is enabled.
Defaults to [SHADOW_CASCADE_ALL](https://api.playcanvas.com/engine/variables/SHADOW_CASCADE_ALL.md), which means the mesh casts shadows into all available cascades.

### visible

```ts
visible: boolean = true
```

Enable rendering for this mesh instance. Use visible property to enable/disable rendering
without overhead of removing from scene. But note that the mesh instance is still in the
hierarchy and still in the draw call list.

### visibleThisFrame

```ts
visibleThisFrame: boolean = false
```

Read this value in the [Scene.EVENT_POSTCULL](https://api.playcanvas.com/engine/classes/Scene.md#event_postcull) event to determine if the object is
actually going to be rendered.

## Accessors

### aabb

```ts
get aabb(): BoundingBox
set aabb(aabb: BoundingBox)
```

Gets the world space axis-aligned bounding box for this mesh instance.

### calculateSortDistance

```ts
get calculateSortDistance(): CalculateSortDistanceCallback | null
set calculateSortDistance(calculateSortDistance: CalculateSortDistanceCallback | null)
```

Gets the callback to calculate sort distance.

### drawBucket

```ts
get drawBucket(): number
set drawBucket(bucket: number)
```

Gets the draw bucket for mesh instance.

### instancingCount

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

Gets the number of instances when using hardware instancing to render the mesh.

### mask

```ts
get mask(): number
set mask(val: number)
```

Gets the light mask of this mesh instance: which [LightComponent](https://api.playcanvas.com/engine/classes/LightComponent.md)s light it.

### material

```ts
get material(): Material | null
set material(material: Material | null)
```

Gets the material used by this mesh instance.

### mesh

```ts
get mesh(): Mesh | null
set mesh(mesh: Mesh | null)
```

Gets the graphics mesh being instanced.

### morphInstance

```ts
get morphInstance(): MorphInstance | null
set morphInstance(val: MorphInstance | null)
```

Gets the morph instance managing morphing of this mesh instance.

### node

```ts
get node(): GraphNode
set node(node: GraphNode)
```

Gets the graph node defining the transform for this instance.

### renderStyle

```ts
get renderStyle(): number
set renderStyle(renderStyle: number)
```

Gets the render style of the mesh instance.

### skinInstance

```ts
get skinInstance(): SkinInstance | null
set skinInstance(val: SkinInstance | null)
```

Gets the skin instance managing skinning of this mesh instance.

## Methods

### deleteParameter

```ts
deleteParameter(name: string): void
```

Deletes a shader parameter on a mesh instance.

**Parameters**

- `name` (`string`): The name of the parameter to delete.

### getIndirectMetaData

```ts
getIndirectMetaData(): Int32Array<ArrayBufferLike>
```

Retrieves the mesh metadata needed for indirect rendering.

**Returns** `Int32Array<ArrayBufferLike>`: - A typed array with 4 elements representing the mesh metadata, which
is typically needed when generating indirect draw call parameters using Compute shader. These
can be provided to the Compute shader using vec4i uniform. The values are based on
[Mesh#primitive](https://api.playcanvas.com/engine/classes/Mesh.md#primitive), stored in this order: [count, base, baseVertex, 0]. The last value is
always zero and is reserved for future use.

### getParameter

```ts
getParameter(name: string): any
```

Retrieves the specified shader parameter from a mesh instance.

**Parameters**

- `name` (`string`): The name of the parameter to query.

**Returns** `any`: The named parameter, or `undefined` if no parameter with that
name is set on this mesh instance.

### setIndirect

```ts
setIndirect(camera: CameraComponent | null, slot: number, count?: number): void
```

Sets the [MeshInstance](https://api.playcanvas.com/engine/classes/MeshInstance.md) to be rendered using indirect rendering, where the GPU,
typically using a Compute shader, stores draw call parameters in a buffer.
Note that this is only supported on WebGPU (see
[GraphicsDevice#supportsIndirectDraw](https://api.playcanvas.com/engine/classes/GraphicsDevice.md#supportsindirectdraw)), and ignored on other platforms, where the
mesh instance renders as a normal draw call.

**Parameters**

- `camera` ([`CameraComponent`](https://api.playcanvas.com/engine/classes/CameraComponent.md) `| null`): Camera component to set indirect data for, or
  null if the indirect slot should be used for all cameras.
- `slot` (`number`): Slot in the buffer to set the draw call parameters. Allocate a slot
  in the buffer by calling [GraphicsDevice#getIndirectDrawSlot](https://api.playcanvas.com/engine/classes/GraphicsDevice.md#getindirectdrawslot). Pass -1 to disable
  indirect rendering for the specified camera (or the shared entry when camera is null).
- `count` (`number`, optional, default `1`): Optional number of consecutive slots to use. Defaults to 1.

### setInstancing

```ts
setInstancing(vertexBuffer: true | VertexBuffer | null, cull?: boolean): void
```

Sets up [MeshInstance](https://api.playcanvas.com/engine/classes/MeshInstance.md) to be rendered using Hardware Instancing.
Note that [instancingCount](https://api.playcanvas.com/engine/classes/MeshInstance.md#instancingcount) is automatically set to the number of vertices of the
vertex buffer when it is provided.

**Parameters**

- `vertexBuffer` (`true |` [`VertexBuffer`](https://api.playcanvas.com/engine/classes/VertexBuffer.md) `| null`): Vertex buffer to hold per-instance vertex data
  (usually world matrices). Pass `true` to enable attributeless instancing where the instance
  index is derived from `gl_InstanceID` / `instance_index` builtins rather than a vertex
  buffer attribute — the caller must set [instancingCount](https://api.playcanvas.com/engine/classes/MeshInstance.md#instancingcount) manually. Pass null to turn
  off hardware instancing.
- `cull` (`boolean`, optional, default `false`): Whether to perform frustum culling on this instance. If true, the whole
  instance will be culled by the camera frustum. This often involves setting
  [RenderComponent#customAabb](https://api.playcanvas.com/engine/classes/RenderComponent.md#customaabb) containing all instances. Defaults to false, which means
  the whole instance is always rendered.

### setMultiDraw

```ts
setMultiDraw(camera: CameraComponent | null, maxCount?: number): DrawCommands | undefined
```

Sets the [MeshInstance](https://api.playcanvas.com/engine/classes/MeshInstance.md) to be rendered using multi-draw, where multiple sub-draws are
executed with a single draw call.

Note: Each call to this method invalidates any previously stored draw command data for the
specified camera.

**Parameters**

- `camera` ([`CameraComponent`](https://api.playcanvas.com/engine/classes/CameraComponent.md) `| null`): Camera component to bind commands to, or null to share
  across all cameras.
- `maxCount` (`number`, optional, default `1`): Maximum number of sub-draws to allocate. Defaults to 1. Pass 0
  to disable multi-draw for the specified camera (or the shared entry when camera is null).

**Returns** [`DrawCommands`](https://api.playcanvas.com/engine/classes/DrawCommands.md) `| undefined`: The commands container to populate with sub-draw commands.

### setParameter

```ts
setParameter(name: string, data: number | number[] | Float32Array<ArrayBufferLike> | Texture): void
```

Sets a shader parameter on a mesh instance. Note that this parameter will take precedence
over parameter of the same name if set on Material this mesh instance uses for rendering.
To change an array value, call this method again with it; the contents of an array are not
guaranteed to be re-read on later draws.

**Parameters**

- `name` (`string`): The name of the parameter to set.
- `data` (`number | number[] | Float32Array<ArrayBufferLike> |` [`Texture`](https://api.playcanvas.com/engine/classes/Texture.md)): The value for the specified parameter.
