| 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 
| 9 | 10 | 11 | 12 | 13 | 14 | 15 | 
| 16 | 17 | 18 | 19 | 20 | 21 | 22 | 
| 23 | 24 | 25 | 26 | 27 | 28 | 29 | 
| 30 | 
													Tags
													
											
												
												- 스토어드 프로시저
 - union find
 - Dijkstra
 - SQL
 - String
 - Brute Force
 - 다익스트라
 - MYSQL
 - Hash
 - Two Points
 - 그래프
 - two pointer
 - DP
 - binary search
 - 이진탐색
 - Trie
 - Stored Procedure
 
													Archives
													
											
												
												- Today
 
- Total
 
codingfarm
6. Direct3D의 그리기 연산 - 정점과 입력 배치(vertex and input layout) 본문
			computer graphics/DX12 book
			
		6. Direct3D의 그리기 연산 - 정점과 입력 배치(vertex and input layout)
scarecrow1992 2021. 6. 1. 23:335장에서 배운 렌더링 파이프라인의 개념적, 수학적 개념을 6장에서는 실제 코드를 통해 렌더링 파이프라인을 구성하고, 정점 셰이더와 픽셀 셰이더를 정의하고, 기하구조를 렌더링 파이프라인에 제출해서 3차원 물체를 그리는 데 필요한 Direct3D API 의 여러 인터페이스와 메서드를 중점적으로 살펴본다.
목표
- 기하 자료의 정의와 저장, 그리기(drawing)를 위한 Direct3D의 여러 인터페이스와 메서드를 파악함
 - 기본적인 정점, 픽셸 셰이더를 작성하는 방법을 배운다.
 - 파이프라인 상태 객체들을 이용해서 렌더링 파이프라인을 구성하는 방법을 파악함
 - 상수 버퍼 자료를 생성해서 파이프라인에 묶는 방법을 배우고, 루트 서명에 익숙해진다.
 
6.1 정점과 입력 배치
- Direct3D의 정점에 공간적 위치 이외의 추가적인 자료를 부여할 수 있음
- ex : 색상, 노말벡터), 텍스처...
 
 
커스텀 정점 형식(Custom Vertex Format) 만들기
- 정점 구조체를 정의한다
 - 입력 배치 서술(input layout description)을 작성
 
정점 구조체
- 정점에 대해 서술할 data를 담는 구조체
 - 정점의 공간적 위치 + 추가적인 자료(color, normal vector, texture...)
 
아래 예제 코드는 서로 다른 두 가지 vertex 형식의 예이다.
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
 | 
 // 위치 + 색상 
struct Vertex1 { 
    XMFLOAT3 Pos; 
    XMFLOAT4 Color; 
}; 
// 위치 + 노말 벡터 + 2개의  
struct Vertex2 { 
    XMFLOAT3 Pos; 
    XMFLOAT3 Normal; 
    XMFLOAT2 Tex0; 
    XMFLOAT2 Tex1; 
}; 
 | 
cs | 
입력 배치 서술
- 정점 구조체의 각 성분에 대해 direct3D에게 통보
 - D3D12_INPUT_LAYOUT_DESC로 대표됨
 - D3D12_INPUT_ELEMENT_DESC 형식의 배열 원소들로 정점 구조체의 각 성분에 대해 서술
- NumElements 값은 vertex struct의 필드 갯수와 동일함
 
 
| 
 1 
2 
3 
4 
 | 
 typedef struct D3D12_INPUT_LAYOUT_DESC { 
  const D3D12_INPUT_ELEMENT_DESC *pInputElementDescs; // array 
 UINT                           NumElements;         // size of array 
} D3D12_INPUT_LAYOUT_DESC; 
 | 
cs | 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
 typedef struct D3D12_INPUT_ELEMENT_DESC { 
  LPCSTR                     SemanticName; 
  UINT                       SemanticIndex; 
  DXGI_FORMAT                Format; 
  UINT                       InputSlot; 
  UINT                       AlignedByteOffset; 
  D3D12_INPUT_CLASSIFICATION InputSlotClass; 
  UINT                       InstanceDataStepRate; 
} D3D12_INPUT_ELEMENT_DESC; 
 | 
cs | 
매개변수
1. LPCSTR SemanticName;
- 성분에 부여된 문자열 이름
 - 정점 셰이더에서 의미소(semantic) 이름으로 쓰이므로, 반드시 유효한 변수이름 이어야 함
 - 정점 구조체의 성분을 정점 셰이더 입력 서명과 대응시킴
 
2. UINT SemanticIndex;
- 의미소(semantic)에 부여된 색인(index)
 - 첫번째 매개변수를 통해 전달된 semantic 이름에 두번째 매개변수의 index를 조합하여 정점 셰이더 입력 서명과 대응시킬 수 있음
 - shader code에서 index가 지정되지 않은 semantic은 index를 0인것으로 간주함
- ex : POSITION은 POSITION0에 해당함
 
 
3. DXGI_FORMAT Format;
- DXGI_FORMAT 열거형의 멤버(resource의 type과 일치함)
 - vertex struct 성분의 자료 형식을 Direct3D에게 알려줌
 
4. UINT InputSlot;
- 이 성분의 자료를 가져올 정점 버퍼 슬롯의 색인
 - Direct3D에서는 총 16개의 정점 버퍼 슬롯을 통해서 정점 자료를 공급할 수 있음
 
5. UINT AlignedByteOffset;
- 지정된 입력 슬롯에서, C++ 정점 구조체의 시작 위치와 이 정점 성분의 시작 위치 사이의 거리를 나타내는 offset(byte 단위)
- float3 : 12 byte
 - float2 : 8 byte
 
 
| 
 1 
2 
3 
4 
5 
6 
 | 
 struct Vertex2 { 
    XMFLOAT3 Pos;        // offset : 0  byte 
    XMFLOAT3 Normal;    // offset : 12 byte 
    XMFLOAT2 Tex0;        // offset : 24 byte 
    XMFLOAT2 tex1;        // offset : 32 byte 
}; 
 | 
cs | 
6. D3D12_INPUT_CLASSFICATION InputSlotClass
- 일단 항상 D3D12_INPUT_PER_VERTEX_DATA를 넣는다.
 - 다른 값은 고급기법인 인스턴싱에 쓰임
 
7. UINT InstanceDataStepRate
- 일단 0을 지정
 
다른 값은 고급기법인 인스턴싱에 쓰임
아래 예를 참고
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
 | 
 struct Vertex { 
    XMFLOAT3 Pos; 
    XMFLOAT3 Normal; 
    XMFLOAT2 Tex0; 
    XMFLOAT2 Tex1; 
}; 
D3D12_INPUT_ELEMENT_DESC vertexDesc[] = { 
    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, 
        D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}, 
    {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, 
        D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}}, 
    {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, 
        D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}}, 
    {"TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 32, 
        D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}} 
}; 
VertexOut VS(float3 iPos : POSITION, 
             float3 iNormal : NORMAL, 
            float2 iTex0 : TEXCOORD0, 
            float2 iTex1 : TEXCOORD1) 
 | 
cs | 
위 코드에서 Vertex구조체의 Pos, Normal, Tex0, Tex1은 각각 Vertex Shader의 iPos, iNormal, iTex0, iTex1에 대응됨
앞서 언급했던 Vertex1과 Vertex2에 대해서는 각각 아래와 같은 Input Layout Description Array가 쓰임
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
 | 
 // 위치 + 색상 
struct Vertex1 { 
    XMFLOAT3 Pos; 
    XMFLOAT4 Color; 
}; 
// 위치 + 노말 벡터 + 2개의  
struct Vertex2 { 
    XMFLOAT3 Pos; 
    XMFLOAT3 Normal; 
    XMFLOAT2 Tex0; 
    XMFLOAT2 Tex1; 
}; 
D3D12_INPUT_ELEMENT_DESC desc1[] = { 
    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, 
        D3D12_INPUT_PER_VERTEX_DATA, 0}, 
    {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, 
        D3D12_INPUT_PER_VERTEX_DATA, 0} 
}; 
D3D12_INPUT_ELEMENT_DESC desc2[] = { 
    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, 
        D3D12_INPUT_PER_VERTEX_DATA, 0}, 
    {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, 
        D3D12_INPUT_PER_VERTEX_DATA, 0}, 
    {"TEXTCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, 
        D3D12_INPUT_PER_VERTEX_DATA, 0}, 
    {"TEXTCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 32, 
        D3D12_INPUT_PER_VERTEX_DATA, 0} 
}; 
 | 
cs | 
'computer graphics > DX12 book' 카테고리의 다른 글
| 6. Direct3D의 그리기 연산 - 색인과 색인 버퍼 (0) | 2021.06.06 | 
|---|---|
| 6. Direct3D의 그리기 연산 - 정점 버퍼(vectex buffer) (0) | 2021.06.02 | 
| Learning DirectX12 (0) | 2021.05.30 | 
| 4. 예제 응용 프로그램 프레임워크 - 메서드 (0) | 2021.02.08 | 
| 4. 시간 측정과 애니메이션 (0) | 2021.02.07 | 
			  Comments