# DrawMeshInstancedIndirect

> Add a "draw mesh with indirect instancing" command.

## Definition

* **Type:** Method
* **Namespace:** [UnityEngine.Rendering](/engine/6000.7/script-reference/unityengine/rendering.md)
* **Assembly:** UnityEngine.CoreModule

## DrawMeshInstancedIndirect(Mesh, int, Material, int, ComputeBuffer, int, MaterialPropertyBlock)

Add a "draw mesh with indirect instancing" command.

```csharp
public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, ComputeBuffer bufferWithArgs, int argsOffset, MaterialPropertyBlock properties)
```

### Parameters

**** (\[Mesh]\(/engine/6000.7/script-reference/unityengine/mesh)): The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) to draw using instancing.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which submesh of the mesh to draw. This only applies to meshes that are composed of several submeshes.**** (\[Material]\(/engine/6000.7/script-reference/unityengine/material)): The [Material](/engine/6000.7/script-reference/unityengine/material.md) to use when drawing the mesh.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which pass of the shader to use, or -1 which renders all passes.**** (\[ComputeBuffer]\(/engine/6000.7/script-reference/unityengine/computebuffer)): A GPU buffer that provides rendering command arguments (See [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md)).**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The offset into the buffer in bytes, where the draw arguments start.**** (\[MaterialPropertyBlock]\(/engine/6000.7/script-reference/unityengine/materialpropertyblock)): Additional Material properties to apply onto the Material just before this Mesh is drawn. See [MaterialPropertyBlock](/engine/6000.7/script-reference/unityengine/materialpropertyblock.md).

### Remarks

This function renders multiple instances of the same Mesh, similar to [Graphics.DrawMeshInstanced](/engine/6000.7/script-reference/unityengine/graphics/drawmeshinstanced.md), but takes the rendering command arguments from `bufferWithArgs`.

You can set up these command arguments with either the CPU or the GPU.

Use [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) to set up the graphics buffer (instead of plain ints) as the layout of this structure can change depending on the platform. The `argsWithBuffer` should contain a single [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) struct at the `argsOffset`.

This function only works on platforms that support [compute shaders](/engine/6000.7/manual/materials-and-shaders/shaders/writing-custom/class-compute-shader.md).

Additional Resources: [Graphics.RenderMesh](/engine/6000.7/script-reference/unityengine/graphics/rendermesh.md), [Graphics.RenderMeshIndirect](/engine/6000.7/script-reference/unityengine/graphics/rendermeshindirect.md), [MaterialPropertyBlock](/engine/6000.7/script-reference/unityengine/materialpropertyblock.md).

The example script below will render a specified mesh 10 times using `DrawMeshInstancedIndirect` when attached to a camera.

```csharp
using UnityEngine;
using UnityEngine.Rendering;

[RequireComponent(typeof(Camera))]
public class ExampleClass : MonoBehaviour
{
    public Material material;
    public Mesh mesh;

    private GraphicsBuffer bufferWithArgs;
    private GraphicsBuffer.IndirectDrawIndexedArgs[] bufferWithArgsData;
    private CommandBuffer cmd;

    void Start()
    {
        // Initialize the GPU-side argument buffer, as well as a CPU-side array to populate it.
        bufferWithArgs = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, 1, GraphicsBuffer.IndirectDrawIndexedArgs.size);
        bufferWithArgsData = new GraphicsBuffer.IndirectDrawIndexedArgs[1];

        // Create a material property block with an additional property that's fed to the shader.
        var matProps = new MaterialPropertyBlock();
        matProps.SetMatrix("_ObjectToWorld", Matrix4x4.Translate(new Vector3(-4.5f, 0, 0)));

        // Populate the GPU-side argument buffer with draw command arguments.
        // This command will render 10 instances of the specified mesh.
        bufferWithArgsData[0] = new GraphicsBuffer.IndirectDrawIndexedArgs
        {
            indexCountPerInstance = mesh.GetIndexCount(0),
            instanceCount = 10,
            baseVertexIndex = 0,
            startIndex = 0,
            startInstance = 0,
        };
        bufferWithArgs.SetData(bufferWithArgsData);

        // Record the indirect draw command onto a command buffer, and add it to the camera.
        // The command buffer is executed whenever the camera renders.
        cmd = new CommandBuffer();
        cmd.DrawMeshInstancedIndirect(mesh, 0, material, 0, bufferWithArgs, 0, matProps);

        GetComponent<Camera>().AddCommandBuffer(CameraEvent.AfterForwardOpaque, cmd);
    }

    void OnDestroy()
    {
        bufferWithArgs?.Release();
        cmd?.Dispose();
    }
}
```

Use the example script with a material that uses the following shader:

```csharp
Shader "ExampleShader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 color : COLOR;
            };

            float4x4 _ObjectToWorld;

            v2f vert(float4 vertex : POSITION, uint instanceID : SV_InstanceID)
            {
                v2f o;

                // Base the position of each instance on the instance ID,
                // so all the instances don't just render at the same position.
                float4 wpos = mul(_ObjectToWorld, vertex + float4(instanceID, 0, 0, 0));
                o.pos = mul(UNITY_MATRIX_VP, wpos);

                // Base the color of each instance on the instance ID as well.
                // Instances will alternate between black and white color.
                o.color = instanceID & 1;

                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                return i.color;
            }
            ENDCG
        }
    }
}
```

## DrawMeshInstancedIndirect(Mesh, int, Material, int, ComputeBuffer, int)

Add a "draw mesh with indirect instancing" command.

```csharp
public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, ComputeBuffer bufferWithArgs, int argsOffset)
```

### Parameters

**** (\[Mesh]\(/engine/6000.7/script-reference/unityengine/mesh)): The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) to draw using instancing.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which submesh of the mesh to draw. This only applies to meshes that are composed of several submeshes.**** (\[Material]\(/engine/6000.7/script-reference/unityengine/material)): The [Material](/engine/6000.7/script-reference/unityengine/material.md) to use when drawing the mesh.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which pass of the shader to use, or -1 which renders all passes.**** (\[ComputeBuffer]\(/engine/6000.7/script-reference/unityengine/computebuffer)): A GPU buffer that provides rendering command arguments (See [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md)).**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The offset into the buffer in bytes, where the draw arguments start.

### Remarks

This function renders multiple instances of the same Mesh, similar to [Graphics.DrawMeshInstanced](/engine/6000.7/script-reference/unityengine/graphics/drawmeshinstanced.md), but takes the rendering command arguments from `bufferWithArgs`.

You can set up these command arguments with either the CPU or the GPU.

Use [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) to set up the graphics buffer (instead of plain ints) as the layout of this structure can change depending on the platform. The `argsWithBuffer` should contain a single [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) struct at the `argsOffset`.

This function only works on platforms that support [compute shaders](/engine/6000.7/manual/materials-and-shaders/shaders/writing-custom/class-compute-shader.md).

Additional Resources: [Graphics.RenderMesh](/engine/6000.7/script-reference/unityengine/graphics/rendermesh.md), [Graphics.RenderMeshIndirect](/engine/6000.7/script-reference/unityengine/graphics/rendermeshindirect.md), [MaterialPropertyBlock](/engine/6000.7/script-reference/unityengine/materialpropertyblock.md).

The example script below will render a specified mesh 10 times using `DrawMeshInstancedIndirect` when attached to a camera.

```csharp
using UnityEngine;
using UnityEngine.Rendering;

[RequireComponent(typeof(Camera))]
public class ExampleClass : MonoBehaviour
{
    public Material material;
    public Mesh mesh;

    private GraphicsBuffer bufferWithArgs;
    private GraphicsBuffer.IndirectDrawIndexedArgs[] bufferWithArgsData;
    private CommandBuffer cmd;

    void Start()
    {
        // Initialize the GPU-side argument buffer, as well as a CPU-side array to populate it.
        bufferWithArgs = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, 1, GraphicsBuffer.IndirectDrawIndexedArgs.size);
        bufferWithArgsData = new GraphicsBuffer.IndirectDrawIndexedArgs[1];

        // Create a material property block with an additional property that's fed to the shader.
        var matProps = new MaterialPropertyBlock();
        matProps.SetMatrix("_ObjectToWorld", Matrix4x4.Translate(new Vector3(-4.5f, 0, 0)));

        // Populate the GPU-side argument buffer with draw command arguments.
        // This command will render 10 instances of the specified mesh.
        bufferWithArgsData[0] = new GraphicsBuffer.IndirectDrawIndexedArgs
        {
            indexCountPerInstance = mesh.GetIndexCount(0),
            instanceCount = 10,
            baseVertexIndex = 0,
            startIndex = 0,
            startInstance = 0,
        };
        bufferWithArgs.SetData(bufferWithArgsData);

        // Record the indirect draw command onto a command buffer, and add it to the camera.
        // The command buffer is executed whenever the camera renders.
        cmd = new CommandBuffer();
        cmd.DrawMeshInstancedIndirect(mesh, 0, material, 0, bufferWithArgs, 0, matProps);

        GetComponent<Camera>().AddCommandBuffer(CameraEvent.AfterForwardOpaque, cmd);
    }

    void OnDestroy()
    {
        bufferWithArgs?.Release();
        cmd?.Dispose();
    }
}
```

Use the example script with a material that uses the following shader:

```csharp
Shader "ExampleShader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 color : COLOR;
            };

            float4x4 _ObjectToWorld;

            v2f vert(float4 vertex : POSITION, uint instanceID : SV_InstanceID)
            {
                v2f o;

                // Base the position of each instance on the instance ID,
                // so all the instances don't just render at the same position.
                float4 wpos = mul(_ObjectToWorld, vertex + float4(instanceID, 0, 0, 0));
                o.pos = mul(UNITY_MATRIX_VP, wpos);

                // Base the color of each instance on the instance ID as well.
                // Instances will alternate between black and white color.
                o.color = instanceID & 1;

                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                return i.color;
            }
            ENDCG
        }
    }
}
```

## DrawMeshInstancedIndirect(Mesh, int, Material, int, ComputeBuffer)

Add a "draw mesh with indirect instancing" command.

```csharp
public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, ComputeBuffer bufferWithArgs)
```

### Parameters

**** (\[Mesh]\(/engine/6000.7/script-reference/unityengine/mesh)): The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) to draw using instancing.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which submesh of the mesh to draw. This only applies to meshes that are composed of several submeshes.**** (\[Material]\(/engine/6000.7/script-reference/unityengine/material)): The [Material](/engine/6000.7/script-reference/unityengine/material.md) to use when drawing the mesh.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which pass of the shader to use, or -1 which renders all passes.**** (\[ComputeBuffer]\(/engine/6000.7/script-reference/unityengine/computebuffer)): A GPU buffer that provides rendering command arguments (See [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md)).

### Remarks

This function renders multiple instances of the same Mesh, similar to [Graphics.DrawMeshInstanced](/engine/6000.7/script-reference/unityengine/graphics/drawmeshinstanced.md), but takes the rendering command arguments from `bufferWithArgs`.

You can set up these command arguments with either the CPU or the GPU.

Use [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) to set up the graphics buffer (instead of plain ints) as the layout of this structure can change depending on the platform. The `argsWithBuffer` should contain a single [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) struct at the `argsOffset`.

This function only works on platforms that support [compute shaders](/engine/6000.7/manual/materials-and-shaders/shaders/writing-custom/class-compute-shader.md).

Additional Resources: [Graphics.RenderMesh](/engine/6000.7/script-reference/unityengine/graphics/rendermesh.md), [Graphics.RenderMeshIndirect](/engine/6000.7/script-reference/unityengine/graphics/rendermeshindirect.md), [MaterialPropertyBlock](/engine/6000.7/script-reference/unityengine/materialpropertyblock.md).

The example script below will render a specified mesh 10 times using `DrawMeshInstancedIndirect` when attached to a camera.

```csharp
using UnityEngine;
using UnityEngine.Rendering;

[RequireComponent(typeof(Camera))]
public class ExampleClass : MonoBehaviour
{
    public Material material;
    public Mesh mesh;

    private GraphicsBuffer bufferWithArgs;
    private GraphicsBuffer.IndirectDrawIndexedArgs[] bufferWithArgsData;
    private CommandBuffer cmd;

    void Start()
    {
        // Initialize the GPU-side argument buffer, as well as a CPU-side array to populate it.
        bufferWithArgs = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, 1, GraphicsBuffer.IndirectDrawIndexedArgs.size);
        bufferWithArgsData = new GraphicsBuffer.IndirectDrawIndexedArgs[1];

        // Create a material property block with an additional property that's fed to the shader.
        var matProps = new MaterialPropertyBlock();
        matProps.SetMatrix("_ObjectToWorld", Matrix4x4.Translate(new Vector3(-4.5f, 0, 0)));

        // Populate the GPU-side argument buffer with draw command arguments.
        // This command will render 10 instances of the specified mesh.
        bufferWithArgsData[0] = new GraphicsBuffer.IndirectDrawIndexedArgs
        {
            indexCountPerInstance = mesh.GetIndexCount(0),
            instanceCount = 10,
            baseVertexIndex = 0,
            startIndex = 0,
            startInstance = 0,
        };
        bufferWithArgs.SetData(bufferWithArgsData);

        // Record the indirect draw command onto a command buffer, and add it to the camera.
        // The command buffer is executed whenever the camera renders.
        cmd = new CommandBuffer();
        cmd.DrawMeshInstancedIndirect(mesh, 0, material, 0, bufferWithArgs, 0, matProps);

        GetComponent<Camera>().AddCommandBuffer(CameraEvent.AfterForwardOpaque, cmd);
    }

    void OnDestroy()
    {
        bufferWithArgs?.Release();
        cmd?.Dispose();
    }
}
```

Use the example script with a material that uses the following shader:

```csharp
Shader "ExampleShader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 color : COLOR;
            };

            float4x4 _ObjectToWorld;

            v2f vert(float4 vertex : POSITION, uint instanceID : SV_InstanceID)
            {
                v2f o;

                // Base the position of each instance on the instance ID,
                // so all the instances don't just render at the same position.
                float4 wpos = mul(_ObjectToWorld, vertex + float4(instanceID, 0, 0, 0));
                o.pos = mul(UNITY_MATRIX_VP, wpos);

                // Base the color of each instance on the instance ID as well.
                // Instances will alternate between black and white color.
                o.color = instanceID & 1;

                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                return i.color;
            }
            ENDCG
        }
    }
}
```

## DrawMeshInstancedIndirect(Mesh, int, Material, int, GraphicsBuffer, int, MaterialPropertyBlock)

Add a "draw mesh with indirect instancing" command.

```csharp
public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, GraphicsBuffer bufferWithArgs, int argsOffset, MaterialPropertyBlock properties)
```

### Parameters

**** (\[Mesh]\(/engine/6000.7/script-reference/unityengine/mesh)): The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) to draw using instancing.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which submesh of the mesh to draw. This only applies to meshes that are composed of several submeshes.**** (\[Material]\(/engine/6000.7/script-reference/unityengine/material)): The [Material](/engine/6000.7/script-reference/unityengine/material.md) to use when drawing the mesh.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which pass of the shader to use, or -1 which renders all passes.**** (\[GraphicsBuffer]\(/engine/6000.7/script-reference/unityengine/graphicsbuffer)): A GPU buffer that provides rendering command arguments (See [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md)).**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The offset into the buffer in bytes, where the draw arguments start.**** (\[MaterialPropertyBlock]\(/engine/6000.7/script-reference/unityengine/materialpropertyblock)): Additional Material properties to apply onto the Material just before this Mesh is drawn. See [MaterialPropertyBlock](/engine/6000.7/script-reference/unityengine/materialpropertyblock.md).

### Remarks

This function renders multiple instances of the same Mesh, similar to [Graphics.DrawMeshInstanced](/engine/6000.7/script-reference/unityengine/graphics/drawmeshinstanced.md), but takes the rendering command arguments from `bufferWithArgs`.

You can set up these command arguments with either the CPU or the GPU.

Use [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) to set up the graphics buffer (instead of plain ints) as the layout of this structure can change depending on the platform. The `argsWithBuffer` should contain a single [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) struct at the `argsOffset`.

This function only works on platforms that support [compute shaders](/engine/6000.7/manual/materials-and-shaders/shaders/writing-custom/class-compute-shader.md).

Additional Resources: [Graphics.RenderMesh](/engine/6000.7/script-reference/unityengine/graphics/rendermesh.md), [Graphics.RenderMeshIndirect](/engine/6000.7/script-reference/unityengine/graphics/rendermeshindirect.md), [MaterialPropertyBlock](/engine/6000.7/script-reference/unityengine/materialpropertyblock.md).

The example script below will render a specified mesh 10 times using `DrawMeshInstancedIndirect` when attached to a camera.

```csharp
using UnityEngine;
using UnityEngine.Rendering;

[RequireComponent(typeof(Camera))]
public class ExampleClass : MonoBehaviour
{
    public Material material;
    public Mesh mesh;

    private GraphicsBuffer bufferWithArgs;
    private GraphicsBuffer.IndirectDrawIndexedArgs[] bufferWithArgsData;
    private CommandBuffer cmd;

    void Start()
    {
        // Initialize the GPU-side argument buffer, as well as a CPU-side array to populate it.
        bufferWithArgs = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, 1, GraphicsBuffer.IndirectDrawIndexedArgs.size);
        bufferWithArgsData = new GraphicsBuffer.IndirectDrawIndexedArgs[1];

        // Create a material property block with an additional property that's fed to the shader.
        var matProps = new MaterialPropertyBlock();
        matProps.SetMatrix("_ObjectToWorld", Matrix4x4.Translate(new Vector3(-4.5f, 0, 0)));

        // Populate the GPU-side argument buffer with draw command arguments.
        // This command will render 10 instances of the specified mesh.
        bufferWithArgsData[0] = new GraphicsBuffer.IndirectDrawIndexedArgs
        {
            indexCountPerInstance = mesh.GetIndexCount(0),
            instanceCount = 10,
            baseVertexIndex = 0,
            startIndex = 0,
            startInstance = 0,
        };
        bufferWithArgs.SetData(bufferWithArgsData);

        // Record the indirect draw command onto a command buffer, and add it to the camera.
        // The command buffer is executed whenever the camera renders.
        cmd = new CommandBuffer();
        cmd.DrawMeshInstancedIndirect(mesh, 0, material, 0, bufferWithArgs, 0, matProps);

        GetComponent<Camera>().AddCommandBuffer(CameraEvent.AfterForwardOpaque, cmd);
    }

    void OnDestroy()
    {
        bufferWithArgs?.Release();
        cmd?.Dispose();
    }
}
```

Use the example script with a material that uses the following shader:

```csharp
Shader "ExampleShader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 color : COLOR;
            };

            float4x4 _ObjectToWorld;

            v2f vert(float4 vertex : POSITION, uint instanceID : SV_InstanceID)
            {
                v2f o;

                // Base the position of each instance on the instance ID,
                // so all the instances don't just render at the same position.
                float4 wpos = mul(_ObjectToWorld, vertex + float4(instanceID, 0, 0, 0));
                o.pos = mul(UNITY_MATRIX_VP, wpos);

                // Base the color of each instance on the instance ID as well.
                // Instances will alternate between black and white color.
                o.color = instanceID & 1;

                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                return i.color;
            }
            ENDCG
        }
    }
}
```

## DrawMeshInstancedIndirect(Mesh, int, Material, int, GraphicsBuffer, int)

Add a "draw mesh with indirect instancing" command.

```csharp
public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, GraphicsBuffer bufferWithArgs, int argsOffset)
```

### Parameters

**** (\[Mesh]\(/engine/6000.7/script-reference/unityengine/mesh)): The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) to draw using instancing.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which submesh of the mesh to draw. This only applies to meshes that are composed of several submeshes.**** (\[Material]\(/engine/6000.7/script-reference/unityengine/material)): The [Material](/engine/6000.7/script-reference/unityengine/material.md) to use when drawing the mesh.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which pass of the shader to use, or -1 which renders all passes.**** (\[GraphicsBuffer]\(/engine/6000.7/script-reference/unityengine/graphicsbuffer)): A GPU buffer that provides rendering command arguments (See [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md)).**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The offset into the buffer in bytes, where the draw arguments start.

### Remarks

This function renders multiple instances of the same Mesh, similar to [Graphics.DrawMeshInstanced](/engine/6000.7/script-reference/unityengine/graphics/drawmeshinstanced.md), but takes the rendering command arguments from `bufferWithArgs`.

You can set up these command arguments with either the CPU or the GPU.

Use [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) to set up the graphics buffer (instead of plain ints) as the layout of this structure can change depending on the platform. The `argsWithBuffer` should contain a single [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) struct at the `argsOffset`.

This function only works on platforms that support [compute shaders](/engine/6000.7/manual/materials-and-shaders/shaders/writing-custom/class-compute-shader.md).

Additional Resources: [Graphics.RenderMesh](/engine/6000.7/script-reference/unityengine/graphics/rendermesh.md), [Graphics.RenderMeshIndirect](/engine/6000.7/script-reference/unityengine/graphics/rendermeshindirect.md), [MaterialPropertyBlock](/engine/6000.7/script-reference/unityengine/materialpropertyblock.md).

The example script below will render a specified mesh 10 times using `DrawMeshInstancedIndirect` when attached to a camera.

```csharp
using UnityEngine;
using UnityEngine.Rendering;

[RequireComponent(typeof(Camera))]
public class ExampleClass : MonoBehaviour
{
    public Material material;
    public Mesh mesh;

    private GraphicsBuffer bufferWithArgs;
    private GraphicsBuffer.IndirectDrawIndexedArgs[] bufferWithArgsData;
    private CommandBuffer cmd;

    void Start()
    {
        // Initialize the GPU-side argument buffer, as well as a CPU-side array to populate it.
        bufferWithArgs = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, 1, GraphicsBuffer.IndirectDrawIndexedArgs.size);
        bufferWithArgsData = new GraphicsBuffer.IndirectDrawIndexedArgs[1];

        // Create a material property block with an additional property that's fed to the shader.
        var matProps = new MaterialPropertyBlock();
        matProps.SetMatrix("_ObjectToWorld", Matrix4x4.Translate(new Vector3(-4.5f, 0, 0)));

        // Populate the GPU-side argument buffer with draw command arguments.
        // This command will render 10 instances of the specified mesh.
        bufferWithArgsData[0] = new GraphicsBuffer.IndirectDrawIndexedArgs
        {
            indexCountPerInstance = mesh.GetIndexCount(0),
            instanceCount = 10,
            baseVertexIndex = 0,
            startIndex = 0,
            startInstance = 0,
        };
        bufferWithArgs.SetData(bufferWithArgsData);

        // Record the indirect draw command onto a command buffer, and add it to the camera.
        // The command buffer is executed whenever the camera renders.
        cmd = new CommandBuffer();
        cmd.DrawMeshInstancedIndirect(mesh, 0, material, 0, bufferWithArgs, 0, matProps);

        GetComponent<Camera>().AddCommandBuffer(CameraEvent.AfterForwardOpaque, cmd);
    }

    void OnDestroy()
    {
        bufferWithArgs?.Release();
        cmd?.Dispose();
    }
}
```

Use the example script with a material that uses the following shader:

```csharp
Shader "ExampleShader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 color : COLOR;
            };

            float4x4 _ObjectToWorld;

            v2f vert(float4 vertex : POSITION, uint instanceID : SV_InstanceID)
            {
                v2f o;

                // Base the position of each instance on the instance ID,
                // so all the instances don't just render at the same position.
                float4 wpos = mul(_ObjectToWorld, vertex + float4(instanceID, 0, 0, 0));
                o.pos = mul(UNITY_MATRIX_VP, wpos);

                // Base the color of each instance on the instance ID as well.
                // Instances will alternate between black and white color.
                o.color = instanceID & 1;

                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                return i.color;
            }
            ENDCG
        }
    }
}
```

## DrawMeshInstancedIndirect(Mesh, int, Material, int, GraphicsBuffer)

Add a "draw mesh with indirect instancing" command.

```csharp
public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, GraphicsBuffer bufferWithArgs)
```

### Parameters

**** (\[Mesh]\(/engine/6000.7/script-reference/unityengine/mesh)): The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) to draw using instancing.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which submesh of the mesh to draw. This only applies to meshes that are composed of several submeshes.**** (\[Material]\(/engine/6000.7/script-reference/unityengine/material)): The [Material](/engine/6000.7/script-reference/unityengine/material.md) to use when drawing the mesh.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Which pass of the shader to use, or -1 which renders all passes.**** (\[GraphicsBuffer]\(/engine/6000.7/script-reference/unityengine/graphicsbuffer)): A GPU buffer that provides rendering command arguments (See [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md)).

### Remarks

This function renders multiple instances of the same Mesh, similar to [Graphics.DrawMeshInstanced](/engine/6000.7/script-reference/unityengine/graphics/drawmeshinstanced.md), but takes the rendering command arguments from `bufferWithArgs`.

You can set up these command arguments with either the CPU or the GPU.

Use [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) to set up the graphics buffer (instead of plain ints) as the layout of this structure can change depending on the platform. The `argsWithBuffer` should contain a single [GraphicsBuffer.IndirectDrawIndexedArgs](/engine/6000.7/script-reference/unityengine/graphicsbuffer/indirectdrawindexedargs.md) struct at the `argsOffset`.

This function only works on platforms that support [compute shaders](/engine/6000.7/manual/materials-and-shaders/shaders/writing-custom/class-compute-shader.md).

Additional Resources: [Graphics.RenderMesh](/engine/6000.7/script-reference/unityengine/graphics/rendermesh.md), [Graphics.RenderMeshIndirect](/engine/6000.7/script-reference/unityengine/graphics/rendermeshindirect.md), [MaterialPropertyBlock](/engine/6000.7/script-reference/unityengine/materialpropertyblock.md).

The example script below will render a specified mesh 10 times using `DrawMeshInstancedIndirect` when attached to a camera.

```csharp
using UnityEngine;
using UnityEngine.Rendering;

[RequireComponent(typeof(Camera))]
public class ExampleClass : MonoBehaviour
{
    public Material material;
    public Mesh mesh;

    private GraphicsBuffer bufferWithArgs;
    private GraphicsBuffer.IndirectDrawIndexedArgs[] bufferWithArgsData;
    private CommandBuffer cmd;

    void Start()
    {
        // Initialize the GPU-side argument buffer, as well as a CPU-side array to populate it.
        bufferWithArgs = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, 1, GraphicsBuffer.IndirectDrawIndexedArgs.size);
        bufferWithArgsData = new GraphicsBuffer.IndirectDrawIndexedArgs[1];

        // Create a material property block with an additional property that's fed to the shader.
        var matProps = new MaterialPropertyBlock();
        matProps.SetMatrix("_ObjectToWorld", Matrix4x4.Translate(new Vector3(-4.5f, 0, 0)));

        // Populate the GPU-side argument buffer with draw command arguments.
        // This command will render 10 instances of the specified mesh.
        bufferWithArgsData[0] = new GraphicsBuffer.IndirectDrawIndexedArgs
        {
            indexCountPerInstance = mesh.GetIndexCount(0),
            instanceCount = 10,
            baseVertexIndex = 0,
            startIndex = 0,
            startInstance = 0,
        };
        bufferWithArgs.SetData(bufferWithArgsData);

        // Record the indirect draw command onto a command buffer, and add it to the camera.
        // The command buffer is executed whenever the camera renders.
        cmd = new CommandBuffer();
        cmd.DrawMeshInstancedIndirect(mesh, 0, material, 0, bufferWithArgs, 0, matProps);

        GetComponent<Camera>().AddCommandBuffer(CameraEvent.AfterForwardOpaque, cmd);
    }

    void OnDestroy()
    {
        bufferWithArgs?.Release();
        cmd?.Dispose();
    }
}
```

Use the example script with a material that uses the following shader:

```csharp
Shader "ExampleShader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 color : COLOR;
            };

            float4x4 _ObjectToWorld;

            v2f vert(float4 vertex : POSITION, uint instanceID : SV_InstanceID)
            {
                v2f o;

                // Base the position of each instance on the instance ID,
                // so all the instances don't just render at the same position.
                float4 wpos = mul(_ObjectToWorld, vertex + float4(instanceID, 0, 0, 0));
                o.pos = mul(UNITY_MATRIX_VP, wpos);

                // Base the color of each instance on the instance ID as well.
                // Instances will alternate between black and white color.
                o.color = instanceID & 1;

                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                return i.color;
            }
            ENDCG
        }
    }
}
```
