> ## 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* 只是網格的子區塊，也就是固定數量的基本型別和頂點。*網格*可以完全由一組 meshlet 定義，而每個 meshlet 都由網格中一組唯一的基本型別組成。我們將已轉換為 meshlet 結構的網格稱為*已 meshlet 化*。

用來建置已 meshlet 化網格的固定基本型別和頂點數量，在整個 meshlet 清單中都是一致的，並定義了每個 meshlet 的大小上限。理想情況下，每個 meshlet 都會盡可能接近此大小，但不一定會填滿。傳統索引緩衝區會由三個新的資料結構取代：meshlet 清單、唯一頂點索引清單，以及基本型別清單。

**圖 1. 依 meshlet 著色的已 meshlet 化網格 (一條龍) 轉譯結果。請注意，meshlet 由具有合理空間一致性的基本型別組成。**

<img src="https://mintcdn.com/microsoft-4404708b/6hkHc7s12mHcTMCE/images/gdk/features/graphics/ms_dragon_meshlets.png?fit=max&auto=format&n=6hkHc7s12mHcTMCE&q=85&s=dc30dfff622025378255edbf728ba775" alt="龍" width="519" height="500" data-path="images/gdk/features/graphics/ms_dragon_meshlets.png" />

下列程式碼範例是執行階段 meshlet 結構的 C++ 實作。此資料完整描述了可轉譯的網格。

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

    // Culling data.
    ...
};

std::vector<MyVertex> Vertices;
std::vector<Meshlet>  Meshlets;
std::vector<uint16_t> UniqueVertexIndices;
std::vector<uint8_t>  PrimitiveIndices;
```

此 meshlet 結構對於 Mesh Shader 轉譯有數項優點。每個 meshlet 都有固定的大小上限，非常適合將固定大小的執行緒群組對應到單一 meshlet，並提供執行緒與頂點/基本型別之間直覺的對應。頂點和基本型別數量事先已知，因此不需要在著色器程式碼中計算。頂點索引已去除重複，因此可消除多餘的頂點轉換和匯出。基本型別索引已在地化至 meshlet 的頂點清單。Meshlet 也透過空間和方向資訊，為剔除提供額外的細微度。

先前的程式碼範例顯示了新 meshlet 緩衝區之間的相互關係。meshlet 清單是執行階段「meshlet」結構的平面清單，該結構至少包含指向唯一頂點索引清單和基本型別清單的位移與數量。唯一頂點索引清單是指向頂點資料緩衝區之索引的去重複清單。基本型別清單定義網格的基本型別，並由指向唯一頂點索引清單的索引組成，這些索引已在地化至 meshlet 的頂點位移。

**圖 2. 顯示 meshlet 緩衝區之間關係的圖表。**

<img src="https://mintcdn.com/microsoft-4404708b/6hkHc7s12mHcTMCE/images/gdk/features/graphics/ms_meshlet_data.png?fit=max&auto=format&n=6hkHc7s12mHcTMCE&q=85&s=e8e9587e2ed7cde69d6bb91adb78971f" alt="顯示 meshlet 緩衝區之間關係的圖表" width="1000" height="283" data-path="images/gdk/features/graphics/ms_meshlet_data.png" />

## 轉換為 meshlet

將傳統索引緩衝區網格 meshlet 化不需要變更美術人員的工作流程，這是製作模型之後的程序性後處理步驟。傳統索引緩衝區也可以在執行階段快速重新產生，因此不需要同時隨附傳統索引緩衝區和 meshlet 緩衝區。Meshlet 化的計算量可能不小，因此建議您離線預先處理。

ATG 提供了一個範例 meshlet 轉換器專案 (包含 C++ 程式庫和命令列工具) 來執行此轉換，可與我們的其他範例一起在 [XBOX 開發人員下載頁面](https://aka.ms/xgddl)上取得。此工具不會修改頂點資料本身，因此建議您在 meshlet 化之前，先對網格資料執行頂點快取最佳化工具，例如 Forsyth 演算法。最佳化工具通常會建立比內容建立工具普遍能產生的更具空間一致性的網格。也可以加入其他啟發學習法，以平衡頂點重複使用與所產生網格結構的有利剔除特性。

## 使用 meshlet 進行轉譯

meshlet 的結構讓使用 Mesh Shader 進行轉譯變得非常容易。將執行緒群組大小宣告為 meshlet 大小上限，並為網格中的每個 meshlet 分派一個執行緒群組。每個執行緒負責處理並匯出一個頂點和基本型別。

下列顯示一個簡單的 Mesh Shader 程式碼範例，用來轉譯已 meshlet 化的網格。首先，載入執行緒群組的 meshlet，並可立即宣告輸出數量。最後，PrimitiveCount 個執行緒負責載入和寫入基本型別索引資料，而 VertexCount 個執行緒會載入用來存取頂點資料的頂點索引，然後進行著色並將其寫入輸出陣列。

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

下列程式碼範例是轉譯 Mesh Shader 之 meshlet 的範例實作。

```
#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,
    out vertices VertexOut verts[MAX_MESHLET_SIZE],
    out indices uint3 tris[MAX_MESHLET_SIZE])
{
    Meshlet m = Meshlets[groupId];

    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 API 概觀](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-api-design)

[Mesh Shader 使用方式](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-usage)

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


## Related topics

- [Meshlet 剔除範例](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-meshlet-culling.md)
- [XBOX Series X|S 上的 Mesh Shader 與 Meshlet](/zh-TW/build/core-features/graphics/newfeatures/ms/index.md)
- [為什麼要使用 Mesh Shader？](/zh-TW/build/core-features/graphics/newfeatures/ms/ms-why.md)
- [XBOX GDK 主機開發的 NDA 主題索引](/zh-TW/nda/nda-overview.md)
