CommandBuffer.DrawMeshInstancedIndirect
Declaration
public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, ComputeBuffer bufferWithArgs, int argsOffset, MaterialPropertyBlock properties);public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, ComputeBuffer bufferWithArgs, int argsOffset);public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, ComputeBuffer bufferWithArgs);public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, GraphicsBuffer bufferWithArgs, int argsOffset, MaterialPropertyBlock properties);public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, GraphicsBuffer bufferWithArgs, int argsOffset);public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, GraphicsBuffer bufferWithArgs);Параметры
| Параметр | Описание |
|---|---|
| сетка | Mesh для рисования с использованием instancing. |
| submeshIndex | Какая подсетка меши должна быть нарисована. Это относится только к мешам, которые состоят из нескольких подсеток. |
| материал | Material для использования при рисовании сетки. |
| shaderPass | Какой проход шейдера использовать, или -1, который отображает все проходы. |
| свойства | Дополнительные свойства Материала, применяемые к Материалу непосредственно перед рисованием этой сетки. См. MaterialPropertyBlock. |
| bufferWithArgs | Буфер GPU, который предоставляет аргументы команды отображения (см. IndirectDrawIndexedArgs). |
| argsOffset | Смещение в байтах, по которому в буфере начинаются аргументы отрисовки. |
Описание
Добавлена команда "нарисовать сетку с косвенным инстанционированием".
Эта функция отображает множественные экземпляры одной и той же Mesh, подобно Graphics.DrawMeshInstanced, но принимает аргументы команды отображения из bufferWithArgs. Вы можете настроить эти аргументы команды либо с CPU или GPU.
Использование IndirectDrawIndexedArgs для настройки графического буфера (вместо обычных ints), так как расположение этой структуры может меняться в зависимости от платформы. argsWithBuffer должен содержать единый IndirectDrawIndexedArgs структура в argsOffset.
Эта функция работает только на платформах, которые поддерживают вычисление шейдеров.
Дополнительные ресурсы: Graphics.RenderMesh, Graphics.RenderMeshIndirect, MaterialPropertyBlock.
Примерный скрипт ниже отобразит указанную сетку 10 раз, используя DrawMeshInstancedIndirect при подключении к камере.
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(); } }
Используйте примерный скрипт с материалом, который использует следующий шейдер:
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
}
}
}