방법: 헐 셰이더 디자인
헐 셰이더는 테 셀레이션 을 구현하기 위해 함께 작동하는 세 단계 중 첫 번째 단계입니다(다른 두 단계는 테셀레이터와 도메인 셰이더임). 이 topics 헐 셰이더를 디자인하는 방법을 보여줍니다.
헐 셰이더에는 기본 헐 셰이더와 패치 상수 함수라는 두 가지 함수가 필요합니다. 헐 셰이더는 각 제어점에서 계산을 구현합니다. 헐 셰이더는 각 패치에 대한 계산을 구현하는 패치 상수 함수도 호출합니다.
헐 셰이더를 디자인한 후에는 방법: 헐 셰이더 만들기를 참조하여 헐 셰이더 를 만드는 방법을 알아봅니다.
헐 셰이더를 디자인하려면
헐 셰이더 입력 컨트롤 및 출력 제어점을 정의합니다.
// 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; };
출력 패치 상수 데이터를 정의합니다.
// 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개(가장자리를 테셀레이션하기 위해)를 정의합니다. 필요한 출력은 삼각형 및 이소라인 도메인에 대해 다릅니다.
고정 함수 테셀레이터는 다른 패치 상수 데이터 또는 제어점과 같은 다른 헐 셰이더 출력을 보지 않습니다. 고정 함수 테셀레이터가 생성하는 각 지점에 대해 호출되는 도메인 셰이더는 모든 헐 셰이더의 출력 제어점 및 모든 출력 패치 상수 데이터를 입력으로 표시합니다. 셰이더는 해당 위치에서 패치를 평가합니다.
패치 상수 함수를 정의합니다. 패치 상수 함수는 각 패치에 대해 한 번 실행되어 전체 패치에 대해 상수인 모든 데이터를 계산합니다(헐 셰이더에서 계산되는 제어점별 데이터와는 반대).
#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 식별됩니다. 구조체는 도메인 유형에 따라 달라지고 삼각형 또는 이소라인 도메인에 대해 다릅니다.
반면에 고정 함수 테셀레이터가 생성하는 각 지점에 대해 도메인 셰이더가 호출되며, 해당 위치에서 패치를 평가하려면 출력 제어점과 출력 패치 상수 데이터(헐 셰이더 모두)를 확인해야 합니다.
헐 셰이더를 정의합니다. 헐 셰이더는 패치 상수 함수를 포함하여 패치의 속성을 식별합니다. 각 출력 제어점에 대해 헐 셰이더가 한 번 호출됩니다.
[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; }
헐 셰이더는 다음 특성을 사용합니다.
- 도메인 특성입니다.
- 분할 특성입니다.
- 출력토폴로지 특성입니다.
- outputcontrolpoints 특성입니다.
- patchconstantfunc 특성입니다. 헐 셰이더는 출력 제어점을 계산합니다. 이 예제에는 16개의 출력 Bezier 제어점이 있습니다.
모든 입력 제어점( VS_CONTROL_POINT_OUTPUT 식별됨)은 각 헐 셰이더 호출에 표시됩니다. 이 예제에는 32개 입력 제어점이 있습니다.
헐 셰이더는 각 패치(SV_PrimitiveID 식별됨)에 대해 출력 제어점당 한 번 호출됩니다(SV_OutputControlPointID 식별됨). 이 특정 셰이더의 목적은 BEZIER 제어점으로 정의된 출력 i를 계산하는 것입니다(이 예제에는 outputcontrolpoints로 정의된 16개의 출력 제어점이 있습니다).
헐 셰이더는 패치당 한 번 루틴(패치 상수 함수)을 실행하여 패치 상수 데이터(테셀레이션 요소를 최소한으로)를 계산합니다. 이와 별도로 헐 셰이더는 각 패치에서 패치 상수 함수(SubDToBezierConstantsHS라고 함)를 실행하여 테셀레이터 단계의 테셀레이션 요소와 같은 패치 상수 데이터를 계산합니다.
관련 항목