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

Graphics.RenderPrimitivesIndexedIndirect

Declaration

public static void RenderPrimitivesIndexedIndirect(ref RenderParams rparams, MeshTopology topology, GraphicsBuffer indexBuffer, GraphicsBuffer commandBuffer, int commandCount = 1, int startCommand = 0);

Параметры

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

Описание

Отображает индексированные примитивы с GPU экземпляром и пользовательским шейдером с аргументами команды отображения из commandBuffer.

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

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

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

#define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs
#include "UnityIndirect.cginc"

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

InitIndirectDrawArgs(0);

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

using UnityEngine;

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

GraphicsBuffer meshTriangles; GraphicsBuffer meshPositions; GraphicsBuffer commandBuf; GraphicsBuffer.IndirectDrawIndexedArgs[] 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.IndirectDrawIndexedArgs.size); commandData = new GraphicsBuffer.IndirectDrawIndexedArgs[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.SetMatrix("_ObjectToWorld", Matrix4x4.Translate(new Vector3(-4.5f, 0, 0))); commandData[0].indexCountPerInstance = mesh.GetIndexCount(0); commandData[0].baseVertexIndex = mesh.GetBaseVertex(0); commandData[0].startIndex = mesh.GetIndexStart(0); commandData[0].instanceCount = 10; commandData[1].indexCountPerInstance = mesh.GetIndexCount(0); commandData[1].baseVertexIndex = mesh.GetBaseVertex(0); commandData[1].startIndex = mesh.GetIndexStart(0); commandData[1].instanceCount = 10; commandBuf.SetData(commandData); Graphics.RenderPrimitivesIndexedIndirect(rp, MeshTopology.Triangles, meshTriangles, 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; };

StructuredBuffer<float3> _Positions; 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[GetIndirectVertexID(svVertexID)]; 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 } } }