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

Graphics.RenderMeshIndirect

Declaration

public static void RenderMeshIndirect(ref RenderParams rparams, Mesh mesh, GraphicsBuffer argsBuffer, int commandCount = 1, int startCommand = 0);

Параметры

Параметр Описание
рпарам Параметры, используемые Unity для отображения сетки.
сетка Mesh для рендеринга.
argsBuffer Графический буфер, предоставляющий аргументы команды рендеринга (см. IndirectDrawIndexedArgs).
commandCount Количество команд рендеринга, которые будут выполнены в argsBuffer.
startCommand Первая команда для выполнения в argsBuffer.

Описание

Отображает несколько экземпляров сетки с помощью GPU instance и аргументов команды отображения из argsBuffer.

Эта функция отображает несколько экземпляров одной и той же сетки, подобно Graphics.RenderMeshInstanced, но принимает аргументы команды отображения из argsBuffer. Вы можете настроить эти аргументы команды либо с CPU, либо с GPU. argsBuffer может содержать несколько команд отображения, которые вы можете выполнить с одним вызовом этого метода. Используйте IndirectDrawIndexedArgs для настройки графического буфера (вместо простых интегов), так как расположение этой структуры может изменяться в зависимости от платформы.

Эта функция работает только на платформах, поддерживающих вычисление шейдеров.

Используйте эту функцию, чтобы нарисовать одну и ту же сетку несколько раз с помощью собственного шейдера и аргументов отображения, управляемых GPU. Используйте RenderParams.worldBounds для определения границ для выделения и сортировки геометрии, отображаемой с помощью метода как единого объекта.

Добавьте следующие строки в раздел pass шейдера для доступа к команде, экземпляру и вершине ID, как указано в UnityIndirect.cginc:

#define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs
#include "UnityIndirect.cginc"

Для настройки функций доступа ID добавьте в начало функции шейдера следующую строку:

InitIndirectDrawArgs(0);

Дополнительные ресурсы: RenderMeshInstanced.

В следующем примере выполняются две команды косвенного отображения. Каждая команда отображает 10 экземпляров Mesh. Соответствующий Материал должен использовать следующий пользовательский шейдер:

using UnityEngine;

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

GraphicsBuffer commandBuf; GraphicsBuffer.IndirectDrawIndexedArgs[] commandData; const int commandCount = 2;

void Start() { commandBuf = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, commandCount, GraphicsBuffer.IndirectDrawIndexedArgs.size); commandData = new GraphicsBuffer.IndirectDrawIndexedArgs[commandCount]; }

void OnDestroy() { commandBuf?.Release(); commandBuf = null; }

void Update() { RenderParams rp = new RenderParams(material); rp.worldBounds = new Bounds(Vector3.zero, 10000*Vector3.one); // use tighter bounds for better FOV culling rp.matProps = new MaterialPropertyBlock(); rp.matProps.SetMatrix("_ObjectToWorld", Matrix4x4.Translate(new Vector3(-4.5f, 0, 0))); commandData[0].indexCountPerInstance = mesh.GetIndexCount(0); commandData[0].instanceCount = 10; commandData[1].indexCountPerInstance = mesh.GetIndexCount(0); commandData[1].instanceCount = 10; commandBuf.SetData(commandData); Graphics.RenderMeshIndirect(rp, mesh, commandBuf, commandCount); } }

Используйте следующий пример шейдера с приведенным выше примером кода C#:

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

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

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

uniform float4x4 _ObjectToWorld;

v2f vert(appdata_base v, uint svInstanceID : SV_InstanceID) { InitIndirectDrawArgs(0); v2f o; uint cmdID = GetCommandID(0); uint instanceID = GetIndirectInstanceID(svInstanceID); float4 wpos = mul(_ObjectToWorld, v.vertex + float4(instanceID, cmdID, 0, 0)); 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 } } }