Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
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
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:33

5장에서 배운 렌더링 파이프라인의 개념적, 수학적 개념을 6장에서는 실제 코드를 통해 렌더링 파이프라인을 구성하고, 정점 셰이더와 픽셀 셰이더를 정의하고, 기하구조를 렌더링 파이프라인에 제출해서 3차원 물체를 그리는 데 필요한 Direct3D API 의 여러 인터페이스와 메서드를 중점적으로 살펴본다.

 

목표

  • 기하 자료의 정의와 저장, 그리기(drawing)를 위한 Direct3D의 여러 인터페이스와 메서드를 파악함
  • 기본적인 정점, 픽셸 셰이더를 작성하는 방법을 배운다.
  • 파이프라인 상태 객체들을 이용해서 렌더링 파이프라인을 구성하는 방법을 파악함
  • 상수 버퍼 자료를 생성해서 파이프라인에 묶는 방법을 배우고, 루트 서명에 익숙해진다.

 

 

6.1 정점과 입력 배치

  • Direct3D의 정점에 공간적 위치 이외의 추가적인 자료를 부여할 수 있음
    • ex : 색상, 노말벡터), 텍스처...

 

커스텀 정점 형식(Custom Vertex Format) 만들기

  1. 정점 구조체를 정의한다
  2. 입력 배치 서술(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, 00,
        D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
    {"NORMAL"0, DXGI_FORMAT_R32G32B32_FLOAT, 012,
        D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}},
    {"TEXCOORD"0, DXGI_FORMAT_R32G32_FLOAT, 024,
        D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0}},
    {"TEXCOORD"1, DXGI_FORMAT_R32G32_FLOAT, 032,
        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, 00,
        D3D12_INPUT_PER_VERTEX_DATA, 0},
    {"COLOR"0, DXGI_FORMAT_R32G32B32A32_FLOAT, 012,
        D3D12_INPUT_PER_VERTEX_DATA, 0}
};
 
D3D12_INPUT_ELEMENT_DESC desc2[] = {
    {"POSITION"0, DXGI_FORMAT_R32G32B32_FLOAT, 00,
        D3D12_INPUT_PER_VERTEX_DATA, 0},
    {"NORMAL"0, DXGI_FORMAT_R32G32B32_FLOAT, 012,
        D3D12_INPUT_PER_VERTEX_DATA, 0},
    {"TEXTCOORD"0, DXGI_FORMAT_R32G32_FLOAT, 024,
        D3D12_INPUT_PER_VERTEX_DATA, 0},
    {"TEXTCOORD"1, DXGI_FORMAT_R32G32_FLOAT, 032,
        D3D12_INPUT_PER_VERTEX_DATA, 0}
};
cs

 

Comments