> ## 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.

# Meshlet 剔除範例

> Meshlet 剔除範例

建議您先閱讀 [Meshlet](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-meshlet-render) 主題。

Meshlet 剔除範例主題呈現了以 Amplification Shader 實作一種稱為 *meshlet 剔除* 之技術的虛擬程式碼。由於 meshlet 的基本型別在理想情況下符合空間和方向上的一致性，因此我們可以為每個 meshlet 儲存有效率的剔除資料。這可用於在 Amplification Shader 中快速針對檢視剔除 meshlet 清單，並只為留存下來的 meshlet 分派 Mesh Shader 執行個體。

此技術從 Amplification Shader 開始，其中每個執行緒處理一個 meshlet。這表示我們必須在命令清單上分派 ceil(MeshletCount / GROUP\_SIZE) 個執行緒群組。

接著，每個 Amplification Shader 執行緒群組負責處理 GROUP\_SIZE 個 meshlet。每個執行緒會針對檢視範圍剔除其 meshlet、決定其匯出位置，然後將其索引寫入承載資料。接著，它會使用 [DispatchMesh](https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#dispatchmesh-intrinsic) 為每個要轉譯的留存 meshlet 分派一個 Mesh Shader 執行緒群組。然後，每個 Mesh Shader 執行緒群組會從承載資料載入其 meshlet，並匯出其幾何。

完整範例可在 [XBOX 開發人員下載頁面](https://aka.ms/xgddl)上找到。

## Amplification Shader

Amplification Shader 的結構與計算著色器相同，但最後最多只會有一個 'DispatchMesh(…)' 呼叫。首先，每個執行緒會載入其 meshlet，並針對檢視加以剔除。接著，執行壓縮常式來決定每個執行緒的最終寫入位置。這也會提供執行緒群組中未剔除 meshlet 的最終數量。最後，meshlet 索引會寫入 groupshared 承載資料，並以留存的 meshlet 數量和承載資料呼叫 DispatchMesh。

下列範例以虛擬程式碼顯示實作 meshlet 剔除的 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);
}
```

## Mesh Shader

此管線的 Mesh Shader 與使用僅含 Mesh Shader 之管線的 meshlet 轉譯非常類似，差別在於我們會從承載資料讀取執行緒群組的 meshlet 索引。承載資料就是由前面的 Amplification Shader 所建立並匯出的相同資料。GroupID 和 DispatchThreadID 會在從叫用的 Amplification Shader 執行緒群組所分派的 Mesh Shader 叢集內進行在地化，而且它們都共用相同的承載資料。

此程式碼範例顯示接續前述 Amplification Shader 的 Mesh 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);
    }
}

```

## 另請參閱

[Mesh Shader 管線概觀](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-overview)

[為什麼要使用 Mesh Shader？](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-why)

[Mesh Shader API 概觀](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-api-design)

[Meshlet](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-meshlet-render)


## Related topics

- [XBOX Series X|S 上的 Mesh Shader 與 Meshlet](/zh-TW/build/core-features/graphics/newfeatures/ms/index.md)
- [Meshlet](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-meshlet-render.md)
- [為什麼要使用 Mesh Shader？](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-why.md)
- [範例](/zh-TW/build/core-features/common/game-streaming/building-touch-layouts/samples/index.md)
- [XBOX 遊戲能源效率基本要點](/zh-TW/build/game-principles/sustainability/energy-efficiency-essentials.md)
