# RenderPrimitivesIndirect(in RenderParams, MeshTopology, GraphicsBuffer, int, int)

> Renders primitives with GPU instancing and a custom shader using rendering command arguments from commandBuffer.

## Definition

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

## RenderPrimitivesIndirect(RenderParams, MeshTopology, GraphicsBuffer, int, int)

```csharp
public static void RenderPrimitivesIndirect(in RenderParams rparams, MeshTopology topology, GraphicsBuffer commandBuffer, int commandCount = 1, int startCommand = 0)
```

### Parameters

**** (\[RenderParams]\(/engine/6000.0/script-reference/unityengine/renderparams)): The parameters Unity uses to render the primitives.**** (\[MeshTopology]\(/engine/6000.0/script-reference/unityengine/meshtopology)): Primitive topology (for example, triangles or lines).**** (\[GraphicsBuffer]\(/engine/6000.0/script-reference/unityengine/graphicsbuffer)): A command buffer that provides rendering command arguments (see [GraphicsBuffer.IndirectDrawArgs](/engine/6000.0/script-reference/unityengine/graphicsbuffer/indirectdrawargs.md)).**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The number of rendering commands to execute in the commandBuffer.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The first command to execute in the commandBuffer.

### Remarks

This function provides a way to control rendering command arguments from GPU to render a given number of primitives and instances. Use /RenderParams.worldBounds/ to define bounds to cull and sort the geometry rendered with the method as a single entity.

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

Add the following lines in the pass section of a shader to access command, instance and vertex ID's as specified in UnityIndirect.cginc: Additional Resources: [Graphics.RenderMeshIndirect](/engine/6000.0/script-reference/unityengine/graphics/rendermeshindirect.md).

```csharp
#define UNITY_INDIRECT_DRAW_ARGS IndirectDrawArgs
#include "UnityIndirect.cginc"
```

Add the following line to the beginning of a shader function to setup the ID access functions:

```csharp
InitIndirectDrawArgs(0);
```

The following example executes two indirect rendering commands. Each command renders 10 Mesh instances. The associated Material must use the below custom shader:

```csharp
using UnityEngine;

public class ExampleClass : MonoBehaviour
{
    public Material material;
    public Mesh mesh;

    GraphicsBuffer meshTriangles;
    GraphicsBuffer meshPositions;
    GraphicsBuffer commandBuf;
    GraphicsBuffer.IndirectDrawArgs[] commandData;
    const int commandCount = 2;

    void Start()
    {
        // note: remember to check "Read/Write" on the mesh asset to get access to the geometry data
        meshTriangles = new GraphicsBuffer(GraphicsBuffer.Target.Structured, mesh.triangles.Length, sizeof(int));
        meshTriangles.SetData(mesh.triangles);
        meshPositions = new GraphicsBuffer(GraphicsBuffer.Target.Structured, mesh.vertices.Length, 3 * sizeof(float));
        meshPositions.SetData(mesh.vertices);
        commandBuf = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, commandCount, GraphicsBuffer.IndirectDrawArgs.size);
        commandData = new GraphicsBuffer.IndirectDrawArgs[commandCount];
    }

    void OnDestroy()
    {
        meshTriangles?.Dispose();
        meshTriangles = null;
        meshPositions?.Dispose();
        meshPositions = null;
        commandBuf?.Dispose();
        commandBuf = null;
    }

    void Update()
    {
        RenderParams rp = new RenderParams(material);
        rp.worldBounds = new Bounds(Vector3.zero, 10000*Vector3.one); // use tighter bounds
        rp.matProps = new MaterialPropertyBlock();
        rp.matProps.SetBuffer("_Triangles", meshTriangles);
        rp.matProps.SetBuffer("_Positions", meshPositions);
        rp.matProps.SetInt("_BaseVertexIndex", (int)mesh.GetBaseVertex(0));
        rp.matProps.SetMatrix("_ObjectToWorld", Matrix4x4.Translate(new Vector3(-4.5f, 0, 0)));
        commandData[0].vertexCountPerInstance = mesh.GetIndexCount(0);
        commandData[0].instanceCount = 10;
        commandData[1].vertexCountPerInstance = mesh.GetIndexCount(0);
        commandData[1].instanceCount = 10;
        commandBuf.SetData(commandData);
        Graphics.RenderPrimitivesIndirect(rp, MeshTopology.Triangles, commandBuf, commandCount);
    }
}
```

Use the following example shader with the above C# example code:

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

            #include "UnityCG.cginc"
            #define UNITY_INDIRECT_DRAW_ARGS IndirectDrawArgs
            #include "UnityIndirect.cginc"

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

            StructuredBuffer<int> _Triangles;
            StructuredBuffer<float3> _Positions;
            uniform uint _BaseVertexIndex;
            uniform float4x4 _ObjectToWorld;

            v2f vert(uint svVertexID: SV_VertexID, uint svInstanceID : SV_InstanceID)
            {
                InitIndirectDrawArgs(0);
                v2f o;
                uint cmdID = GetCommandID(0);
                uint instanceID = GetIndirectInstanceID(svInstanceID);
                float3 pos = _Positions[_Triangles[GetIndirectVertexID(svVertexID)] + _BaseVertexIndex];
                float4 wpos = mul(_ObjectToWorld, float4(pos + float3(instanceID, cmdID, 0.0f), 1.0f));
                o.pos = mul(UNITY_MATRIX_VP, wpos);
                o.color = float4(cmdID & 1 ? 0.0f : 1.0f, cmdID & 1 ? 1.0f : 0.0f, instanceID / float(GetIndirectInstanceCount()), 0.0f);
                return o;
            }

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