다음을 통해 공유


방법: 헐 셰이더 디자인

헐 셰이더는 테 셀레이션 을 구현하기 위해 함께 작동하는 세 단계 중 첫 번째 단계입니다(다른 두 단계는 테셀레이터와 도메인 셰이더임). 이 topics 헐 셰이더를 디자인하는 방법을 보여줍니다.

헐 셰이더에는 기본 헐 셰이더와 패치 상수 함수라는 두 가지 함수가 필요합니다. 헐 셰이더는 각 제어점에서 계산을 구현합니다. 헐 셰이더는 각 패치에 대한 계산을 구현하는 패치 상수 함수도 호출합니다.

헐 셰이더를 디자인한 후에는 방법: 헐 셰이더 만들기를 참조하여 헐 셰이더 를 만드는 방법을 알아봅니다.

헐 셰이더를 디자인하려면

  1. 헐 셰이더 입력 컨트롤 및 출력 제어점을 정의합니다.

    // Input control point
    struct VS_CONTROL_POINT_OUTPUT
    {
        float3 vPosition : WORLDPOS;
        float2 vUV       : TEXCOORD0;
        float3 vTangent  : TANGENT;
    };
    
    // Output control point
    struct BEZIER_CONTROL_POINT
    {
        float3 vPosition    : BEZIERPOS;
    };
    
  2. 출력 패치 상수 데이터를 정의합니다.

    // Output patch constant data.
    struct HS_CONSTANT_DATA_OUTPUT
    {
        float Edges[4]        : SV_TessFactor;
        float Inside[2]       : SV_InsideTessFactor;
    
        float3 vTangent[4]    : TANGENT;
        float2 vUV[4]         : TEXCOORD;
        float3 vTanUCorner[4] : TANUCORNER;
        float3 vTanVCorner[4] : TANVCORNER;
        float4 vCWts          : TANWEIGHTS;
    };
    

    쿼드 도메인의 경우 고정 함수 테셀레이터는 테셀레이션할 양을 알아야 하므로 쿼드 도메인의 경우 SV_TessFactor 에지 테셀레이션 요소 4개(가장자리를 테셀레이션하기 위해)를 정의합니다. 필요한 출력은 삼각형 및 이소라인 도메인에 대해 다릅니다.

    고정 함수 테셀레이터는 다른 패치 상수 데이터 또는 제어점과 같은 다른 헐 셰이더 출력을 보지 않습니다. 고정 함수 테셀레이터가 생성하는 각 지점에 대해 호출되는 도메인 셰이더는 모든 헐 셰이더의 출력 제어점 및 모든 출력 패치 상수 데이터를 입력으로 표시합니다. 셰이더는 해당 위치에서 패치를 평가합니다.

  3. 패치 상수 함수를 정의합니다. 패치 상수 함수는 각 패치에 대해 한 번 실행되어 전체 패치에 대해 상수인 모든 데이터를 계산합니다(헐 셰이더에서 계산되는 제어점별 데이터와는 반대).

    
    #define MAX_POINTS 32
    
    // Patch Constant Function
    HS_CONSTANT_DATA_OUTPUT SubDToBezierConstantsHS( 
        InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POINTS> ip,
        uint PatchID : SV_PrimitiveID )
    {   
        HS_CONSTANT_DATA_OUTPUT Output;
    
        // Insert code to compute Output here
    
        return Output;
    }
    

    패치 상수 함수의 속성은 다음과 같습니다.

    • 하나의 입력은 패치 ID를 포함하는 변수를 지정하고 SV_PrimitiveID 시스템 값으로 식별됩니다(셰이더 모델 4 의 의미 체계 참조).
    • 한 입력 매개 변수는 입력 제어점이며 이 예제의 VS_CONTROL_POINT_OUTPUT 선언되어 있습니다. 패치 함수는 각 패치에 대한 모든 입력 제어점을 볼 수 있으며, 이 예제에서는 패치당 32개의 제어점이 있습니다.
    • 최소한 함수는 SV_TessFactor 식별되는 테셀레이터 단계에 대한 패치별 테셀레이션 요소를 계산해야 합니다. 쿼드 도메인에는 에지에 대한 네 가지 테셀레이션 요소와 패치 내부를 테셀레이션하기 위한 두 가지 추가 요소( SV_InsideTessFactor 식별됨)가 필요합니다. 고정 함수 테셀레이터는 다른 헐 셰이더 출력(예: 패치 상수 데이터 또는 제어점)을 보지 않습니다.
    • 출력은 일반적으로 구조체에 의해 정의되며 이 예제에서 HS_CONSTANT_DATA_OUTPUT 식별됩니다. 구조체는 도메인 유형에 따라 달라지고 삼각형 또는 이소라인 도메인에 대해 다릅니다.

    반면에 고정 함수 테셀레이터가 생성하는 각 지점에 대해 도메인 셰이더가 호출되며, 해당 위치에서 패치를 평가하려면 출력 제어점과 출력 패치 상수 데이터(헐 셰이더 모두)를 확인해야 합니다.

  4. 헐 셰이더를 정의합니다. 헐 셰이더는 패치 상수 함수를 포함하여 패치의 속성을 식별합니다. 각 출력 제어점에 대해 헐 셰이더가 한 번 호출됩니다.

    [domain("quad")]
    [partitioning("integer")]
    [outputtopology("triangle_cw")]
    [outputcontrolpoints(16)]
    [patchconstantfunc("SubDToBezierConstantsHS")]
    BEZIER_CONTROL_POINT SubDToBezierHS( 
        InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POINTS> ip, 
        uint i : SV_OutputControlPointID,
        uint PatchID : SV_PrimitiveID )
    {
        VS_CONTROL_POINT_OUTPUT Output;
    
        // Insert code to compute Output here.
    
        return Output;
    }
    

    헐 셰이더는 다음 특성을 사용합니다.

모든 입력 제어점( VS_CONTROL_POINT_OUTPUT 식별됨)은 각 헐 셰이더 호출에 표시됩니다. 이 예제에는 32개 입력 제어점이 있습니다.

헐 셰이더는 각 패치(SV_PrimitiveID 식별됨)에 대해 출력 제어점당 번 호출됩니다(SV_OutputControlPointID 식별됨). 이 특정 셰이더의 목적은 BEZIER 제어점으로 정의된 출력 i를 계산하는 것입니다(이 예제에는 outputcontrolpoints로 정의된 16개의 출력 제어점이 있습니다).

헐 셰이더는 패치당 한 번 루틴(패치 상수 함수)을 실행하여 패치 상수 데이터(테셀레이션 요소를 최소한으로)를 계산합니다. 이와 별도로 헐 셰이더는 각 패치에서 패치 상수 함수(SubDToBezierConstantsHS라고 함)를 실행하여 테셀레이터 단계의 테셀레이션 요소와 같은 패치 상수 데이터를 계산합니다.

Direct3D 11을 사용하는 방법

테셀레이션 개요