> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# メッシュレット カリングの例

> メッシュレット カリングの例

まず [メッシュレット](/build/core-features/graphics/newfeatures/ms/ms-meshlet-render) のトピックを読むことをお勧めします。

このメッシュレット カリングの例のトピックでは、*メッシュレット カリング* と呼ばれる手法を Amplification Shader で実装した疑似コードを示します。メッシュレットのプリミティブは、理想的には空間的および方向的な一貫性を持っているため、メッシュレットごとに効率的なカリング データを保存できます。これを利用して、Amplification Shader 内でメッシュレット リストをビューに対して素早くカリングし、生き残ったメッシュレットに対してのみメッシュ シェーダー インスタンスをディスパッチできます。

この手法は、各スレッドが 1 つのメッシュレットを処理する Amplification Shader から始まります。つまり、コマンド リストに対して ceil(MeshletCount / GROUP\_SIZE) 個のスレッドグループをディスパッチする必要があります。

その後、各 Amplification Shader スレッドグループは GROUP\_SIZE 個のメッシュレットを処理する責任を持ちます。各スレッドは自身のメッシュレットをビュー フラスタムに対してカリングし、エクスポート スロットを決定し、そのインデックスをペイロード データに書き込みます。次に [DispatchMesh](https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#dispatchmesh-intrinsic) を使用して、レンダリングのために生き残った各メッシュレットに対して 1 つのメッシュ シェーダー スレッドグループをディスパッチします。次に、各メッシュ シェーダー スレッドグループはペイロード データからメッシュレットを読み込み、そのジオメトリをエクスポートします。

完全なサンプルは、[XBOX Developer Downloads ページ](https://aka.ms/xgddl)で入手できます。

## Amplification Shader

Amplification Shader の構造はコンピュート シェーダーと同一ですが、末尾で最大 1 回の 'DispatchMesh(…)' 呼び出しで終わります。まず、各スレッドが自身のメッシュレットを読み込んでビューに対してカリングします。次にコンパクション ルーチンを実行して、各スレッドの最終的な書き込み場所を決定します。これによりスレッドグループ内でカリングされずに残ったメッシュレット数の最終的なカウントも得られます。最後に、メッシュレット インデックスがグループ共有のペイロード データに書き込まれ、生き残ったメッシュレット数とペイロード データを引数として DispatchMesh が呼び出されます。

以下の例は、メッシュレット カリングを実装した Amplification Shader の疑似コードです。

```
#define GROUP_SIZE 128

struct Meshlet
{
    // Meshlet data.
    uint VertexOffset;
    uint VertexCount;
    uint PrimitiveOffset;
    uint PrimitiveCount;

    // Local Culling data.
    float4 BoundingSphere;
    float4 NormalCone;
};

StructuredBuffer<Meshlet> Meshlets : register(t0);

cbuffer ViewProps : register(b0)
{
    float4x4 ViewMat;
    float4x4 ViewProjMat;
    float3   ViewPosition;
};

struct MyPayload 
{ 
    uint MeshletIndices[GROUP_SIZE]; 
};

groupshared MyPayload payload;

bool CullTests(Meshlet m) { ... }
void CalcPayloadIndexAndCount(bool isCulled, out index, out count) { ... }

[NumThreads(GROUP_SIZE, 1, 1)] 
void main(
    uint dispatchThreadId : SV_DispatchThreadID,
    uint groupThreadId : SV_GroupThreadID
)
{
    Meshlet meshlet = Meshlets[dispatchThreadId];
    bool isCulled = CullTests(meshlet);
    
    uint index, count;
    CalcPayloadIndexAndCount(groupThreadId, isCulled, index, count);
    
    if (!isCulled)
    {
        payload.MeshletIndices[index] = dispatchThreadId;
    }

    DispatchMesh(count, 1, 1, payload);
}
```

## メッシュ シェーダー

パイプラインのメッシュ シェーダーは、ペイロード データからスレッドグループのメッシュレット インデックスを読み取る点を除いて、メッシュ シェーダーのみのパイプラインを使用したメッシュレット レンダリングと非常によく似ています。ペイロード データは、前段の Amplification Shader によって構築されエクスポートされたものと同じデータです。GroupID と DispatchThreadID は、呼び出し元の Amplification Shader スレッドグループからディスパッチされたメッシュ シェーダー クラスター内でローカル化されており、それらすべてが同じペイロード データを共有します。

以下のコード例は、前述の Amplification Shader に続くメッシュ シェーダーを示しています。

```
#define MAX_MESHLET_SIZE 128

StructureBuffer<MyVertex>   Vertices;
StructureBuffer<Meshlet>    Meshlets;
StructuredBuffer<uint>      UniqueVertexIndices;
StructureBuffer<uint3>      PrimitiveIndices;

VertexOut TransformVertex(MyVertex v) { ... }

[NumThreads(MAX_MESHLET_SIZE, 1, 1)]
[OutputTopology("triangle")]
void main(
    uint groupThreadId : SV_GroupIndex,
    uint groupId : SV_GroupID,
    in payload MyPayload payload,
    out vertices VertexOut verts[MAX_MESHLET_SIZE],
    out indices uint3 tris[MAX_MESHLET_SIZE])
{
    uint meshletIndex = payload.MeshletIndices[groupId];
    Meshlet m = Meshlets[meshletIndex];

    SetMeshOutputCounts(m.VertCount, m.PrimCount);

    if (groupThreadId < m.PrimCount) 
    {
        tris[groupThreadId] = PrimitiveIndices[m.PrimOffset + groupThreadId];
    }

    if (groupThreadId < m.VertCount) 
    {
        uint index = UniqueVertexIndices[m.VertOffset + groupThreadId];
        MyVertex vin = Vertices[index];

        verts[groupThreadId] = TransformVertex(vin);
    }
}

```

## 関連項目

[メッシュ シェーダー パイプラインの概要](/build/core-features/graphics/newfeatures/ms/ms-overview)

[なぜメッシュ シェーダーなのか?](/build/core-features/graphics/newfeatures/ms/ms-why)

[メッシュ シェーダー API の概要](/build/core-features/graphics/newfeatures/ms/ms-api-design)

[メッシュレット](/build/core-features/graphics/newfeatures/ms/ms-meshlet-render)


## Related topics

- [メッシュレット](/ja-jp/build/core-features/graphics/newfeatures/ms/ms-meshlet-render.md)
- [XBOX Series X|S のメッシュ シェーダーとメッシュレット](/ja-jp/build/core-features/graphics/newfeatures/ms/index.md)
- [なぜメッシュ シェーダーなのか?](/ja-jp/build/core-features/graphics/newfeatures/ms/ms-why.md)
- [メッシュ シェーダー パイプラインの概要](/ja-jp/build/core-features/graphics/newfeatures/ms/ms-overview.md)
- [Android 用プッシュ通知](/ja-jp/services/playfab/live-service-management/game-configuration/title-communications/push-notifications/push-notifications-for-android.md)
