Version: Unity 6.2 (6000.2)
LanguageEnglish
  • C#

CommandBuffer.DrawMeshInstancedIndirect

Suggest a change

Success!

Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.

Close

Submission failed

For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.

Close

Cancel

Declaration

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

Declaration

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

Declaration

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

Declaration

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

Declaration

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

Declaration

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

Parameters

Parameter Description
mesh The Mesh to draw using instancing.
submeshIndex Which submesh of the mesh to draw. This only applies to meshes that are composed of several submeshes.
material The Material to use when drawing the mesh.
shaderPass Which pass of the shader to use, or -1 which renders all passes.
properties Additional Material properties to apply onto the Material just before this Mesh is drawn. See MaterialPropertyBlock.
bufferWithArgs A GPU buffer that provides rendering command arguments (See IndirectDrawIndexedArgs).
argsOffset The offset into the buffer in bytes, where the draw arguments start.

Description

Add a "draw mesh with indirect instancing" command.

This function renders multiple instances of the same Mesh, similar to Graphics.DrawMeshInstanced, but takes the rendering command arguments from bufferWithArgs. You can set up these command arguments with either the CPU or the GPU.

Use IndirectDrawIndexedArgs 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 IndirectDrawIndexedArgs struct at the argsOffset.

This function only works on platforms that support compute shaders.

Additional resources: Graphics.RenderMesh, Graphics.RenderMeshIndirect, MaterialPropertyBlock.

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

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:

          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 } } }