> ## 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) 항목을 읽어 보시기 바랍니다.

메시렛 컬링 예제 항목에서는 *메시렛 컬링*이라는 기법의 증폭 셰이더 구현 의사코드를 소개합니다. 메시렛의 프리미티브는 이상적으로 공간적 및 방향적 일관성을 따르므로, 메시렛별로 효율적인 컬링 데이터를 저장할 수 있습니다. 이를 통해 증폭 셰이더에서 뷰에 대해 메시렛 목록을 신속하게 컬링하고 살아남은 메시렛에 대해서만 메시 셰이더 인스턴스를 디스패치할 수 있습니다.

이 기법은 각 스레드가 단일 메시렛을 처리하는 증폭 셰이더로 시작합니다. 이는 명령 리스트에서 ceil(MeshletCount / GROUP\_SIZE)개의 스레드그룹을 디스패치해야 함을 의미합니다.

그런 다음 각 증폭 셰이더 스레드그룹은 GROUP\_SIZE개의 메시렛을 처리할 책임이 있습니다. 각 스레드는 뷰 프러스텀에 대해 자신의 메시렛을 컬링하고, 내보내기 슬롯을 결정한 다음, 자신의 인덱스를 페이로드 데이터에 씁니다. 그런 다음 [DispatchMesh](https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#dispatchmesh-intrinsic)를 사용하여 렌더링할 각 살아남은 메시렛에 대해 하나의 메시 셰이더 스레드그룹을 디스패치합니다. 그런 다음 각 메시 셰이더 스레드그룹은 페이로드 데이터에서 자신의 메시렛을 로드하고 지오메트리를 내보냅니다.

전체 샘플은 [XBOX 개발자 다운로드 페이지](https://aka.ms/xgddl)에서 찾을 수 있습니다.

## 증폭 셰이더

증폭 셰이더 구조는 컴퓨트 셰이더와 동일하지만, 최대 하나의 'DispatchMesh(…)' 호출로 끝납니다. 먼저 각 스레드는 자신의 메시렛을 로드하고 뷰에 대해 컬링합니다. 다음으로, 각 스레드의 최종 쓰기 위치를 결정하기 위해 컴팩션 루틴이 수행됩니다. 이는 또한 스레드그룹에 대한 컬링되지 않은 메시렛의 최종 개수를 제공합니다. 마지막으로, 메시렛 인덱스가 그룹 공유 페이로드 데이터에 기록되고, 살아남은 메시렛 개수와 페이로드 데이터로 DispatchMesh가 호출됩니다.

다음 예제는 의사코드로 메시렛 컬링을 구현하는 증폭 셰이더를 보여줍니다.

```
#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);
}
```

## 메시 셰이더

파이프라인의 메시 셰이더는 스레드그룹의 메시렛 인덱스를 페이로드 데이터에서 읽는다는 점을 제외하면 메시 셰이더 전용 파이프라인을 사용한 메시렛 렌더링과 매우 유사합니다. 페이로드 데이터는 앞선 증폭 셰이더에서 구축되고 내보낸 것과 동일한 데이터입니다. GroupID와 DispatchThreadID는 호출하는 증폭 셰이더 스레드그룹에서 디스패치된 메시 셰이더 클러스터로 로컬화되며, 모두 동일한 페이로드 데이터를 공유합니다.

이 코드 예제는 이전 증폭 셰이더 다음에 오는 메시 셰이더를 보여줍니다.

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

- [메시렛](/ko/build/core-features/graphics/newfeatures/ms/ms-meshlet-render.md)
- [XBOX Series X|S의 메시 셰이더 및 메시렛](/ko/build/core-features/graphics/newfeatures/ms/index.md)
- [메시 셰이더를 사용하는 이유는?](/ko/build/core-features/graphics/newfeatures/ms/ms-why.md)
- [메시 셰이더 파이프라인 API 개요](/ko/build/core-features/graphics/newfeatures/ms/ms-api-design.md)
- [메시 셰이더 파이프라인 개요](/ko/build/core-features/graphics/newfeatures/ms/ms-overview.md)
