版本: Unity 6 (6000.0)
语言英语
  • C#

Graphics.RenderPrimitivesIndexedIndirect

建议更改

成功!

感谢您帮助我们改进 Unity 文档的质量。虽然我们无法接受所有提交内容,但我们会阅读用户提出的每项建议更改,并在适用时进行更新。

关闭

提交失败

由于某种原因,您的建议更改无法提交。请<a>稍后再试</a>。感谢您抽出时间帮助我们改进 Unity 文档的质量。

关闭

取消

声明

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

参数

rparams Unity 用于渲染图元的参数。
topology 图元拓扑结构(例如,三角形或线条)。
indexBuffer 渲染图元的索引缓冲区。
commandBuffer 提供渲染命令参数的命令缓冲区(请参阅 IndirectDrawIndexedArgs)。
commandCount commandBuffer 中执行的渲染命令数量。
startCommand commandBuffer 中执行的第一个命令。

描述

使用 GPU 实例化和来自 commandBuffer 的渲染命令参数,通过自定义着色器渲染索引图元。

此函数允许您从 GPU 控制渲染命令参数,以渲染给定数量的索引图元和实例。使用 RenderParams.worldBounds 定义边界,以剔除和对使用此方法作为单个实体渲染的几何体进行排序。

此函数仅在支持 计算着色器 的平台上有效。

在着色器的传递部分添加以下行,以访问 UnityIndirect.cginc 中指定的命令、实例和顶点 ID:A: RenderMeshIndirect

#define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs
#include "UnityIndirect.cginc"

在着色器函数开头添加以下行,以设置 ID 访问函数

InitIndirectDrawArgs(0); // pass SV_DrawID semantic value here for multi-draw support

以下示例执行两个间接渲染命令。每个渲染命令都渲染 10 个网格实例。关联的材质必须使用以下自定义着色器。

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