테셀레이션 단계
Direct3D 11 런타임은 GPU에서 저 세부도 분할 표면을 상위 세부도 원형으로 변환하는 테셀레이션을 구현하는 새로운 세 단계를 지원합니다. 공간 분할은 상위 표면을 렌더링에 적합한 구조로 타일링(또는 분할)합니다.
그래픽 파이프라인은 하드웨어에서 공간 분할을 구현하여 하위 세부도(다각형 수가 적음) 모델을 평가하고 상위 세부도로 렌더링할 수 있습니다. 소프트웨어 공간 분할이 가능하지만 하드웨어에서 구현된 공간 분할은 모델 크기에 시각적 세부 정보를 추가하고 새로 고침 빈도를 마비시키지 않고 놀라울 정도의 시각적 세부 정보를 생성할 수 있습니다(변위 매핑에 대한 지원 포함).
테셀레이션 혜택
테셀레이션:
- 메모리와 대역폭을 많이 절약하여 애플리케이션이 저해상도 모델에서 더 자세한 표면을 렌더링할 수 있습니다. Direct3D 11 파이프라인에서 구현된 공간 분리 기술은 변위 매핑도 지원하므로 엄청난 양의 표면 세부 정보를 생성할 수 있습니다.
- 즉석에서 계산할 수 있는 연속 또는 뷰 종속 세부 수준과 같은 확장 가능한 렌더링 기술을 지원합니다.
- 낮은 빈도로 값비싼 계산을 수행하여 성능을 향상시킵니다(하위 세부 모델에서 계산 수행). 여기에는 사실적 애니메이션을 위한 혼합 형태 또는 모프 대상을 사용한 혼합 계산이나 충돌 탐지 또는 연체 역학을 위한 물리 계산이 포함될 수 있습니다.
Direct3D 11 파이프라인은 하드웨어에서 테셀레이션을 구현하여 CPU에서 GPU로 작업을 오프로드합니다. 그러므로 애플리케이션이 많은 수의 모프 대상 및/또는 보다 정교한 스킨 지정/변형 모델을 구현하는 경우 성능이 현저히 개선될 수 있습니다. 새 테셀레이션 기능에 액세스하려면 몇 가지 새로운 파이프라인 단계에 대해 알아보아야 합니다.
새 파이프라인 단계
공간 분할은 GPU를 사용하여 사각형 패치, 삼각형 패치 또는 등치선에서 구성된 표면으로부터 보다 세부적인 표면을 계산합니다. 상위 표면을 개산하기 위해 공간 분할 요소를 사용하여 각 패치가 삼각형, 점 또는 선으로 세분화됩니다. Direct3D 11 파이프라인은 세 가지 새로운 파이프라인 단계를 사용하여 테셀레이션을 구현합니다.
- 헐 셰이더 단계 - 각 입력 패치(쿼드, 삼각형 또는 선)에 해당하는 기하 도형 패치(및 패치 상수)를 생성하는 프로그래밍 가능한 셰이더 단계입니다.
- 테셀레이터 단계 - 기하 도형 패치를 나타내는 도메인의 샘플링 패턴을 만들고 이러한 샘플을 연결하는 더 작은 개체(삼각형, 점 또는 선) 집합을 생성하는 고정 함수 파이프라인 단계입니다.
- 도메인 셰이더 단계 - 각 도메인 샘플에 해당하는 꼭짓점 위치를 계산하는 프로그래밍 가능한 셰이더 단계입니다.
다음 다이어그램은 Direct3D 11 파이프라인의 새 단계를 강조 표시합니다.
다음 다이어그램은 공간 분할 단계의 진행을 보여 줍니다. 진행은 저 세부도 분할 표면에서 시작됩니다. 다음 진행은 해당하는 기하 도형 패치, 도메인 샘플 및 이러한 샘플을 연결하는 삼각형을 포함하는 입력 패치를 강조 표시합니다. 마지막 진행은 이러한 샘플에 해당하는 꼭짓점을 강조 표시합니다.
Hull-Shader 단계
패치당 한 번 호출되는 헐 셰이더는 하위 표면을 정의하는 입력 제어점을 패치를 구성하는 제어점으로 변환합니다. 또한 패치별 계산을 수행하여 테셀레이션 단계 및 도메인 단계에 대한 데이터를 제공합니다. 가장 간단한 블랙박스 수준에서 헐 셰이더 단계는 다음 다이어그램과 비슷합니다.
헐 셰이더는 HLSL 함수를 사용하여 구현되며 다음과 같은 속성이 있습니다.
- 셰이더 입력은 1~32개 제어점 사이입니다.
- 셰이더 출력은 공간 분할 요인의 수에 관계없이 1에서 32까지의 제어점입니다. 헐 셰이더의 제어점 출력은 도메인 셰이더 단계에서 사용할 수 있습니다. 패치 상수 데이터는 도메인 셰이더에서 사용할 수 있습니다. 테셀레이션 요소는 도메인 셰이더 및 테셀레이션 단계에서 사용할 수 있습니다.
- 공간 분할 요인은 각 패치를 얼마나 세분화할지 결정합니다.
- 셰이더는 테셀레이터 단계에서 필요한 상태를 선언합니다. 여기에는 제어점의 수, 패치 면의 유형, 공간 분할 시 사용하는 분할의 유형 등이 포함됩니다. 이 정보는 일반적으로 셰이더 코드 앞에 선언으로 표시됩니다.
- 헐 셰이더 단계에서 에지 테셀레이션 요소를 = 0 또는 NaN으로 설정하면 패치가 컬링됩니다. 그 결과로, 분할기 단계가 실행 또는 실행되지 않을 수도 있고, 도메인 셰이더가 실행되지 않을 수도 있으며, 해당 패치에 대한 출력이 표시되지 않을 수도 있습니다.
더 깊은 수준에서 헐 셰이더는 실제로 제어점 단계와 하드웨어에서 병렬로 실행되는 패치 상수 단계의 두 단계로 작동합니다. HLSL 컴파일러는 헐 셰이더에서 병렬 처리 내용을 추출하고 하드웨어를 구동하는 바이트코드로 인코딩합니다.
- 제어점 단계는 각 제어점에 대해 한 번 작동하며, 패치를 위한 제어점을 읽고, 하나의 출력 제어점(ControlPointID로 식별됨)을 생성합니다.
- 패치 상수 단계는 패치당 한 번씩 작동하며, 가장자리 공간 분할 요인 및 기타 패치별 상수를 생성합니다. 내부적으로 많은 패치 상수 단계가 동시에 실행될 수 있습니다. 패치 상수 단계는 모든 입출력 제어점에 대한 읽기 전용 액세스 권한을 가집니다.
헐 셰이더의 예는 다음과 같습니다.
[patchsize(12)]
[patchconstantfunc(MyPatchConstantFunc)]
MyOutPoint main(uint Id : SV_ControlPointID,
InputPatch<MyInPoint, 12> InPts)
{
MyOutPoint result;
...
result = TransformControlPoint( InPts[Id] );
return result;
}
헐 셰이더를 만드는 예제는 방법: 헐 셰이더 만들기를 참조하세요.
테셀레이터 단계
테셀레이터는 헐 셰이더를 파이프라인에 바인딩하여 초기화된 고정 함수 단계입니다( 방법: 테셀레이터 단계 초기화 참조). 분할기 단계의 목적은 도메인(사각형, 삼각형 또는 선)을 여러 개의 더 작은 개체(삼각형, 점 또는 선)로 세분화하는 것입니다. 분할기는 정규(0~1) 좌표계에서 정식 도메인을 타일링합니다. 예를 들어 사각형 도메인은 단위 정사각형으로 공간 분할됩니다.
분할기는 헐 셰이더 단계로부터 전달되는 공간 분할 요소(도메인을 얼마나 세부적으로 공간 분할할지 지정) 및 분할 유형(패치를 분할하는 데 사용할 알고리즘을 지정)을 사용하여 패치당 헌 번 작동합니다. 분할기는 uv(및 선택적으로 w) 좌표 및 표면 토폴로지를 도메인 셰이더 단계로 출력합니다.
내부적으로 테셀레이터는 다음 두 단계로 작동합니다.
- 첫 번째 작업 단계에서는 32비트 부동 소수점 연산으로 공간 분할 요소를 처리하여 반올림 문제를 해결하고, 매우 작은 요소를 처리하고, 요소를 환원 및 결합합니다.
- 두 번째 작업 단계에서는 선택한 분할 유형에 따라 점 또는 토폴로지 목록을 생성합니다. 이 작업 단계가 분할기 단계의 핵심 작업으로, 16비트 분수 및 고정 소수점 연산을 사용합니다. 고정 소수점 연산은 허용 가능한 정밀도를 유지하면서도 하드웨어 가속을 사용할 수 있게 해줍니다. 예를 들어 64미터의 너비의 패치가 있을 경우 이 정밀도는 2mm 해상도로 점을 배치할 수 있습니다.
분할 유형 | 범위 |
---|---|
fractional_odd | [1...63] |
fractional_even | TessFactor range: [2..64] |
정수 | TessFactor range: [1..64] |
pow2 | TessFactor range: [1..64] |
Domain-Shader 단계
도메인 셰이더는 출력 패치에서 세분화된 지점의 꼭짓점 위치를 계산합니다. 도메인 셰이더는 테셀레이터 단계 출력 지점당 한 번 실행되며 다음 다이어그램과 같이 테셀레이터 단계 출력 UV 좌표, 헐 셰이더 출력 패치 및 헐 셰이더 출력 패치 상수에 대한 읽기 전용 액세스 권한이 있습니다.
도메인 셰이더의 속성은 다음과 같습니다.
- 도메인 셰이더는 테셀레이터 단계에서 출력 좌표당 한 번 호출됩니다.
- 도메인 셰이더는 헐 셰이더 단계의 출력 제어점을 사용합니다.
- 도메인 셰이더는 꼭짓점의 위치를 출력합니다.
- 입력은 제어점, 패치 상수 데이터 및 테셀레이션 요소를 포함한 헐 셰이더 출력입니다. 예를 들어, 테셀레이션 요소에는 고정 함수 테셀레이터에서 사용하는 값과 원시 값(예: 정수 테셀레이션으로 반올림하기 전)이 포함될 수 있습니다.
도메인 셰이더가 완료되면 테셀레이션이 완료되고 파이프라인 데이터가 다음 파이프라인 단계(기하 도형 셰이더, 픽셀 셰이더 등)로 계속됩니다. 인접한 기본 요소(예를 들어 삼각형당 6개 꼭짓점)를 기대하는 기하 도형 셰이더는 공간 분할이 활성화된 경우 유효하지 않습니다. 이로 인해 디버그 계층에서 문제를 삼을 정의되지 않은 동작이 발생합니다.
다음은 도메인 셰이더의 예입니다.
void main( out MyDSOutput result,
float2 myInputUV : SV_DomainPoint,
MyDSInput DSInputs,
OutputPatch<MyOutPoint, 12> ControlPts,
MyTessFactors tessFactors)
{
...
result.Position = EvaluateSurfaceUV(ControlPoints, myInputUV);
}
테셀레이션 단계를 초기화하기 위한 API
Tessellation은 두 개의 새로운 프로그래밍 가능한 셰이더 단계인 헐 셰이더와 도메인 셰이더로 구현됩니다. 이러한 새 셰이더 단계는 셰이더 모델 5에 정의된 HLSL 코드로 프로그래밍됩니다. 새 셰이더 대상은 hs_5_0 및 ds_5_0. 모든 프로그래밍 가능한 셰이더 단계와 마찬가지로 셰이더가 DSSetShader 및 HSSetShader와 같은 API를 사용하여 파이프라인에 바인딩될 때 런타임에 전달된 컴파일된 셰이더에서 하드웨어에 대한 코드가 추출됩니다. 그러나 먼저 CreateHullShader 및 CreateDomainShader 와 같은 API를 사용하여 셰이더 를 만들어야 합니다.
헐 셰이더를 만들어 헐 셰이더 단계에 바인딩하여(그러면 분할기 단계가 자동으로 설정됨) 공간 분할을 활성화합니다. 또한 공간 분할된 패치에서 최종 꼭짓점 위치를 생성하기 위해 도메인 셰이더를 만들어 도메인 셰이더 단계에 바인딩해야 합니다. 테셀레이션을 사용하도록 설정하면 입력 어셈블러 단계에 대한 데이터 입력은 패치 데이터여야 합니다. 즉, 입력 어셈블러 토폴로지는 IASetPrimitiveTopology로 설정된 D3D11_PRIMITIVE_TOPOLOGY 패치 상수 토폴로지여야 합니다.
공간 분할을 사용하지 않으려면 헐 셰이더 및 도메인 셰이더를 NULL로 설정합니다. geometry-shader 단계나 스트림 출력 단계에서는 헐 셰이더 출력 제어 지점 또는 패치 데이터를 읽을 수 없습니다.
이 열거형의 확장인 입력 어셈블러 단계에 대한 새로운 토폴로지입니다.
enum D3D11_PRIMITIVE_TOPOLOGY
물론, 새로운 프로그래밍 가능한 셰이더 단계에서는 상수 버퍼, 샘플 및 셰이더 리소스를 적절한 파이프라인 단계에 바인딩하기 위해 다른 상태를 설정해야 합니다. 이러한 새 ID3D11Device 메서드는 이 상태를 설정하기 위해 구현됩니다.
방법:
설명서에는 테셀레이션 단계를 초기화하는 예제도 포함되어 있습니다.
항목 | 설명 |
---|---|
방법: 헐 셰이더 만들기 |
헐 셰이더를 만듭니다. |
방법: 헐 셰이더 디자인 |
헐 셰이더를 디자인합니다. |
방법: 테셀레이터 단계 초기화 |
테셀레이션 단계를 초기화합니다. |
방법: 도메인 셰이더 만들기 |
도메인 셰이더를 만듭니다. |
방법: 도메인 셰이더 디자인 |
도메인 셰이더를 만듭니다. |