(사실 이해했는지 모르겠다. 어렴풋이 느껴질 뿐... 그래도 그 느낌을 정리한다.)
1. Tessellation
- Shader를 이용해서 GPU에게 점 (삼각형)을 새로 생성해달라고 하는 거다.
( App에서 작업을 줄이고, GPU의 작업을 늘리는 느낌 )
- 그래픽스 파이프라인에서 Vertex Shader 다음에 작성할 수 있는 단계다.
그래픽 파이프라인 - Win32 apps | Microsoft Learn
- (Constants) Hull Shader + Tessellator + Domain Shader 단계를 가진다.
- 여기서 프로그래머가 제어 하는 것은 (Constants) Hull Shader와 Domain Shader를 제어할 수 있다.
- App에서 Topology format을 TYPE_PATCH로 넘겨준 Vertex Patch들을 가지고
- (Constants) Hull Shader : 어떻게 Tessellator에게 어떤 방식으로 점을 생성하도록 요청할 지
- Domain Shader : Tessellator 생성된 점들을 어떻게 사용할 것인지를 제어한다.
- Patch는 점 1개에서 32개 까지 가질 수 있다... 이 점들은 제어점의 역할을 한다.
(대충 흐름을 정리하면)
- Patch에 있는 제어점들을 기준으로 테셀레이션을 얼마나 할지, 정하는 것을 Hull Shader에 포함된 patch constant func에서 정한다. (그리고 Hull Shader에서는 제어점의 추가적인 변환 같은게 있으면 처리하는 것이고)
- Hull Shader에서 작업이 끝나면 GPU에다가 테셀레이션을 요청한다. 그러면, Hull Shader에 작성한 것에 따라 Vertex 들이 새로 생겼을 것이다.
- 이 각각의 Vertex에 대해서 Domain Shader안의 로직이 실행이 된다.
- Domain Shader에 입력으로 들어오는 float2의 uv 좌표는 패치로 들어온 제어점 공간안에 상대적인 위치를 나타낸다.
- 그래서 보간을 하던, 새로운 작업을 하던, 제어점과 uv를 이용해서 새로 생성된 vertex의 world 좌표 상 + Homogenous 좌표 상의 위치를 구한다.
2. App에서 해줘야 하는 것
- 테셀레이션의 제어점을 Vertex Buffer View로 IA 단계에 넘겨주는데, Topology Type을
D3D_PRIMITIVE_TOPOLOGY_xx_CONTROL_POINT_PATCHLIST로 넘겨주어야 한다. (xx는 제어점 개수)
- 그리고 PSO에서도 PrimitiveTopologyType을 D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH 해서 파이프 라인이 Patch가 들어온 다는 것을 알아야 한다.
3. 언급할 만한 예제에서 사용한 방법(구조)
- 예제 1번에서는 테셀레이터로 생성된 점들을 patch 상의 이중선형 보간을 이용해서 xz 평면상의 월드 좌표를 구했고,
- 그 xz 좌표와 곡면 함수를 이용해서 적절히 굴곡이 있는 산의 모양을 만들었다.
- 그리고 pass Constant로 넘어온 카메라 좌표와, patch와 거리를 고려하여 Tessellation 횟수를 결정하여 최적화 과정을 연습하였다.
- 예제 2번에서는 테셀레이터로 생성된 점들을 베지어 곡선의 제어점으로 사용하고, 3차 베지어 곡선을 쉽게 구할 수 있게 해주는, 베른 슈타인 베이시스를 각 축별로 적용하여서 베지어 곡면을 생성하였다.
4. 연습 문제
(클릭하면 커집니다.)
연습 문제 1
- Hull Shader
- Domain Shader 와 App에서 해주는 일
- 연습 문제 2
- Hull Shader 코드는 연습문제 1번과 같다.
- Domain Shader 코드는 새로 생성된 점들을 구 위에 사영시키는 코드가 추가 되었다.
- App에 작성한 코드
- 20 면체를 생성하고, 그걸 3각형 패치로 나눠서 뿌려주기 위해 SubGeo로 만들어서 넣어주고
- SubGeo를 전부 그려주는 DrawAllSubRenderItems() 함수를 따로 만들어서 사용했다.
연습 문제 3
- 그냥 SV_TessFactor와 SV_InsideTessFactor의 값을 이리저리 바꿔가면서 테스트 해보는 것이다.
연습 문제 4
- 테레셀레이터의 파티션 모드를 float에서도 할 수 있도록 바꿔보는 연습이다.
연습 문제 5
- 2차 베지어 곡면을 베이시스, 매개변수 방정식
연습 문제 6
- 대충 제어점들 바꿔가면서 확인하는 것이다.
연습 문제 7
- 2차 베지어 곡면을 그려보기 (constrol point 9개)
연습 문제 8
- 베지어 곡면 위에서 노멀을 구하는 것은, 곡면을 만드는 베이시스 함수를 축별로 편미분 한것을 외적하면 된다.
연습 문제 9
-
- 베지어 삼각형(Bezier Triangle)을 그리는 연습을 하는 것이다.
- 참조한 곳 Bézier triangle - Wikipedia
- 제어점 basis(?)야 양의 값을 가질때를 나타내는 공식이긴한데, 작동은 해서 그냥 올린다.
- Domain Shader
5. 메모용
- dcl_resource (sm4 - asm) - Win32 apps | Microsoft Learn
- Domain Shader 출력 구조체에 Sementic을 넣고 값을 초기화 안하면 domain shader 는 downstream 뭐시기라서 upstream에만 사용할 수 있는 semantic 을 사용했다고 error를 뱉는다.
- output이 제한이 되나...문서를 보면 출력도 32-bit Vertex Data Output만 뱉는다고 한다. (D3D11 문서이긴 하지만...)
- Direct3D 11.3 Functional Specification (microsoft.github.io)
- 어쨌든 값을 제대로 초기화 해줘야한다.
책 : DirectX 12를 이용한 3D 게임 프로그래밍 입문
'Programming > D3D12' 카테고리의 다른 글
[책공부] Instancing / Frustum Culling + chap 16 연습 문제 (0) | 2024.02.21 |
---|---|
[책공부] Dynamic Indexing / FPS Camera + chap 15 연습 문제 (0) | 2024.02.19 |
[책공부] Compute Shader + chap 13 연습 문제 (0) | 2024.02.02 |
[책공부] Geometry Shader + chap 12 연습 문제 (0) | 2024.01.30 |
[책공부] Stencil 예제 + chap 11 연습 문제 (0) | 2024.01.23 |