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

Graphics.RenderMeshIndirect

建议修改

成功!

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

关闭

提交失败

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

关闭

取消

声明

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

参数

rparams Unity 用于渲染网格的参数。
mesh 要渲染的网格
commandBuffer 提供渲染命令参数的命令缓冲区(参见 IndirectDrawIndexedArgs)。
commandCount commandBuffer 中要执行的渲染命令数量。
startCommand commandBuffer 中要执行的第一个命令。

描述

使用 GPU 实例化和来自 commandBuffer 的渲染命令参数来渲染网格的多个实例。

此函数渲染相同网格的多个实例,类似于 Graphics.RenderMeshInstanced,但从 commandBuffer 获取渲染命令参数。您可以使用 CPU 或 GPU 设置这些命令参数。 commandBuffer 可以包含多个渲染命令,您可以在一次调用此方法时执行这些命令。在受支持的平台上,Unity 可以通过将单个多绘制渲染命令提交到低级 API 来进一步优化多命令调用的 CPU 性能。使用 IndirectDrawIndexedArgs 设置命令缓冲区(而不是简单的整数),因为此结构的布局可能会根据平台而有所不同。

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

使用此函数使用自定义着色器和 GPU 控制的渲染参数多次绘制同一个网格。使用 RenderParams.worldBounds 定义边界以剔除和排序使用此方法渲染的几何体作为单个实体。

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

#define UNITY_INDIRECT_DRAW_ARGS IndirectDrawIndexedArgs
#include "UnityIndirect.cginc"

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

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

其他资源:RenderMeshInstanced

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

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