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

Graphics.RenderMeshInstanced

Declaration

public static void RenderMeshInstanced(ref RenderParams rparams, Mesh mesh, int submeshIndex, T[] instanceData, int instanceCount = -1, int startInstance = 0);
public static void RenderMeshInstanced(ref RenderParams rparams, Mesh mesh, int submeshIndex, List<T> instanceData, int instanceCount = -1, int startInstance = 0);
public static void RenderMeshInstanced(RenderParams rparams, Mesh mesh, int submeshIndex, NativeArray<T> instanceData, int instanceCount = -1, int startInstance = 0);

Параметры

Параметр Описание
рпарам Параметры, используемые Unity для отображения экземпляров сетки.
сетка Mesh для рендеринга.
submeshIndex Индекс подсетки Unity отображается, когда сетка содержит несколько Материалов (подсеток). Для сетки с одним Материалом используйте значение 0.
instanceData Массив данных экземпляра, используемый для отображения экземпляров.
instanceCount Количество экземпляров для отображения. Когда этот аргумент равен -1 (по умолчанию), Unity отображает все экземпляры от startInstance до конца массива instanceData.
startInstance Первый экземпляр в instanceData для отображения.

Описание

Отображает множественные экземпляры сетки с использованием GPU экземпляров.

Эта функция отображает меши для текущего кадра, подобно Graphics.RenderMesh, но имеет более высокую производительность благодаря использованию экземпляров GPU.

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

Прошлое instanceData может быть либо массивом Matrix4x4 (преобразование объекта в мир на экземпляр) или собственную структуру данных. instanceData является пользовательской структурой данных, структура может содержать следующие члены:

          Matrix4x4 objectToWorld; // mandatory: Specifies object-to-world transformation matrix.
uint renderingLayerMask; // optional: Specifies rendering layer mask per instance. If not defined, uses the renderLayerMask passed in RenderParams.
Matrix4x4 prevObjectToWorld; // optional: Specifies previous frame object-to-world transformation matrix (used for motion vector rendering).

Эти члены могут идти в структуре в любом порядке, но при использовании должны иметь именно указанные имена и типы. Инстансированный рендеринг игнорирует любые другие члены, которые вы включаете в структуру для собственных нужд. В следующем примере пользовательская структура объявляет обязательный objectToWorld члена, факультативного renderingLayerMask члена и таможенного weight член (игнорируется RenderMeshIndirect функции).

public struct MyInstanceData
{
    Matrix4x4 objectToWorld; // We must specify object-to-world transformation for each instance
    uint renderingLayerMask; // In addition we also like to specify rendering layer mask per instence.
    float weight; // Just some additional per-instance data unrelated to rendering
};

Для использования световых зондов, установите RenderParams.lightProbeUsage на LightProbeUsage.BlendProbes для автоматической настройки световых зондов для каждого экземпляра. Или используйте LightProbeUsage.CustomProvided для предоставления пользовательских данных световых зондов вручную.

В качестве альтернативы, если ваш проект использует встроенный Render Pipeline, вы можете передать ссылку на компонент LPPV и LightProbeUsage.UseProxyVolume. При этом все экземпляры получат выборку объема для полос L0 и L1 данных Светового зонда. Если вы хотите дополнить данные L2 и данные окклюзии, используйте MaterialPropertyBlock.

Вы можете отобразить только максимум 1023 экземпляра одновременно. Максимум зависит от количества данных, используемых для каждого экземпляра.

По умолчанию Unity использует матрицу objectToWorld и матрицу worldToObject для каждого экземпляра, что означает, что вы можете отобразить максимум 511 экземпляров одновременно. Чтобы удалить матрицу worldToObject из данных экземпляра, добавьте #pragma instancing_options assumeuniformscaling в шейдер.

Unity выводит InvalidOperationException, если Материал не имеет Material.enableInstancing установленных на true, если текущая платформа не поддерживает API, или если GPU instancing недоступен. Дополнительные сведения см. в SystemInfo.supportsInstancing.

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

В следующем примере отображается 10 мешей с использованием RenderMeshInstanced. В этом скрипте необходимо включить "GPU Instancing" на Материале:

using UnityEngine;

public class ExampleClass : MonoBehaviour { public Material material; public Mesh mesh; const int numInstances = 10;

void Update() { RenderParams rp = new RenderParams(material); Matrix4x4[] instData = new Matrix4x4[numInstances]; for(int i=0; i<numInstances; ++i) instData[i] = Matrix4x4.Translate(new Vector3(-4.5f+i, 0.0f, 5.0f)); Graphics.RenderMeshInstanced(rp, mesh, 0, instData); } }

В следующем примере используется пользовательская структура данных экземпляра, задающая преобразование из пространства объекта в мировое и маску слоёв рендеринга для отрисовки каждого экземпляра. Для наглядности структура также объявляет пользовательский член данных myOtherData который не используется для рендеринга, но может быть полезен для других целей:

using UnityEngine;

public class ExampleClass : MonoBehaviour { public Material material; public Mesh mesh; const int numInstances = 10;

struct MyInstanceData { public Matrix4x4 objectToWorld; public float myOtherData; public uint renderingLayerMask; };

void Update() { RenderParams rp = new RenderParams(material); MyInstanceData[] instData = new MyInstanceData[numInstances]; for(int i=0; i<numInstances; ++i) { instData[i].objectToWorld = Matrix4x4.Translate(new Vector3(-4.5f+i, 0.0f, 5.0f)); instData[i].renderingLayerMask = (i & 1) == 0 ? 1u : 2u; } Graphics.RenderMeshInstanced(rp, mesh, 0, instData); } }