Version: 2023.2
言語: 日本語
BatchRendererGroup オブジェクトの初期化
バッチの作成

メッシュとマテリアルの登録

メッシュマテリアル は Unity のマネージ C# オブジェクトなので、Burst C# コードからは使用できません。したがって、これらを BRG の描画コマンドで使用するには、BRG に事前登録する必要があります。

メッシュオブジェクトの登録には BatchRendererGroup.RegisterMesh を使用し、マテリアルオブジェクトの登録には BatchRendererGroup.RegisterMaterial を使用してください。前者の関数は BatchMeshID を返し、後者の関数は BatchMaterialIDを を返します。これらは Burst 互換ハンドルを含むプレーンなデータ構造体で、間違ったハンドルタイプの使用によるエラーを防ぐために、強く型付けされています。

メッシュオブジェクトとマテリアルオブジェクトの登録は、ランタイムを含め、いつでも行えます。ただし、以下の条件だけは満たしている必要があります。

  • メッシュオブジェクトやマテリアルオブジェクトは、BatchRendererGroup によってレンダリングに使用される前に登録されている必要があります。
  • マテリアルは DOTS インスタンシングをサポートしている必要があります。

不要になったメッシュオブジェクトやマテリアルオブジェクトは登録解除することもできます。これはメッシュオブジェクトやマテリアルオブジェクトをアンロードする場合には行う必要があります。BatchRendererGroup.Dispose は、すべてのアセットの登録を自動的に解除します。

ノート: BatchMeshID や BatchMaterialID はシリアル化できません。これらは、その登録された BatchRendererGroup でのみ有効で、登録が解除されたり、その BatchRendererGroup が存在しなくなると無効になります。また BatchMeshID と BatchMaterialID は、メッシュあるいはマテリアルオブジェクトが強制的にアンロードされた場合にも無効になります (例: Unity がメッシュあるいはマテリアルオブジェクトを含むシーンをアンロードした場合)。

同じメッシュあるいはマテリアルのオブジェクトを複数回登録することも可能です。これは、メッシュあるいはマテリアルの登録を、どのメッシュあるいはマテリアルが既に登録されているか把握せずに行いたい場合に役立ちます。この場合、BatchRenderer は以下のように内部的に登録回数をカウントします。

  • メッシュあるいはマテリアルオブジェクトが 1 つ登録されるたびに、BatchRendererGroup は参照カウントを 1 増加させます。
  • メッシュあるいはマテリアルオブジェクトの登録が解除されるたびに、BatchRendererGroup は参照カウントを 1 減少させます。これにより参照カウントが 0 になると、BatchRendererGroup はそのメッシュあるいはマテリアルの登録を解除します。後からそのメッシュあるいはマテリアルを描画コマンドで使用するには、再度登録する必要があります。
  • 既に登録されているメッシュあるいはマテリアルで RegisterMesh または RegisterMaterial を呼び出すと、前回の呼び出しと同じ BatchMeshID または BatchMaterialID が返されます。ただし、BatchRendererGroup がメッシュあるいはマテリアルの登録を完全に解除した場合は、再登録の際に異なる ID が返される可能性があります。

ノート: BRG は、フレーム内の最初の OnPerformCulling コールバックメソッドの後に、メッシュあるいはマテリアルオブジェクトに加えられた変更を検査します。つまり Unity は、それ以前に発生したすべての変更を考慮します。これには最初のコールバック自体で行った変更は含まれますが、そのコールバックがスケジュールしたジョブで発生した変更は含まれません。それ以降にメッシュあるいはマテリアルのオブジェクトに変更を加えると、未定義の動作が発生します。

BatchRendererGroup オブジェクトにメッシュやマテリアルを登録する方法については、以下のコードサンプルを参照してください。このコードサンプルは、BatchRendererGroup オブジェクトの初期化 に掲載のものをベースに構築されています。

using System;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Rendering;

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

    private BatchRendererGroup m_BRG;

    private BatchMeshID m_MeshID;
    private BatchMaterialID m_MaterialID;

    private void Start()
    {
        m_BRG = new BatchRendererGroup(this.OnPerformCulling, IntPtr.Zero);
        m_MeshID = m_BRG.RegisterMesh(mesh);
        m_MaterialID = m_BRG.RegisterMaterial(material);
    }

    private void OnDisable()
    {
        m_BRG.Dispose();
    }

    public unsafe JobHandle OnPerformCulling(
        BatchRendererGroup rendererGroup,
        BatchCullingContext cullingContext,
        BatchCullingOutput cullingOutput,
        IntPtr userContext)
    {
        // この単純な例はジョブを使用しないので、空の JobHandle を返します。
        // パフォーマンス負荷の高いアプリケーションの場合は、Burst ジョブを使用して
        // カリングと描画コマンドの出力を実装することが推奨されます。その場合、この関数は
        // Burst ジョブの終了時に完了するハンドルを返します。
        return new JobHandle();
    }
}

登録されたメッシュとマテリアルを使用する描画コマンドを作成するには、その描画コマンドのインスタンスに使用するデータ (Transform 行列など) を前もって提供する必要があります。BatchRendererGroup は、バッチと呼ばれる概念を使用して、各インスタンスに使用するデータを提供します。詳細は次のトピック バッチの作成 を参照してください。

BatchRendererGroup オブジェクトの初期化
バッチの作成