Unity 6.3
0 онлайн 89 гостей 3 в системе
Вход

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