DX11) InputLayout
InputLayout
InputLayout은 GPU가 정점 데이터를 어떻게 해석해야 하는지 정의하는 DirectX11의 필수적인 요소다.
Vertex Buffer에 저장된 데이터를 VertexShader가 올바르게 읽을 수 있도록 형식을 지정하는 역할이다.
InputLayout이 필요한 이유
DirectX11에서 버텍스 데이터를 GPU에 전달할 때, GPU는 정점의 구조를 자동으로 인식할 수 없다. 따라서, InputLayout을 사용하여 각 정점이 어떤 속성(Position, Color, Texture 등)을 포함하고 있는지 설명해야 한다.
- Vertex Buffer 데이터의 구조를 GPU에 전달 (어떤 데이터인지 알려줘야 함)
- Vertex Shader가 정점 데이터를 올바르게 읽을 수 있도록 설정
- 다양한 정점 데이터 구조를 지원하기 위해 필요 (예: 위치만 있는 정점, 텍스처 좌표가 포함된 정점 등)
- GPU의 파이프라인에서 데이터 해석 방식(메모리 레이아웃) 명확
InputLayout의 역할
InputLayout은 “정점 버퍼의 데이터 형식을 Vertex Shader에서 사용할 수 있도록 매핑”하는 역할이다.
기능 | 설명 |
---|---|
정점 데이터 구조 정의 | Position, Color, Normal, UV 등의 속성을 GPU에 전달 |
각 속성의 데이터 타입 지정 | DXGI_FORMAT_R32G32B32_FLOAT 같은 데이터 형식 지정 |
데이터의 바이트 정렬(Offset) 지정 | 정점 구조체 내에서 특정 속성이 어디에 위치하는지 설정 |
정점 데이터가 정점당(Per-Vertex)인지 인스턴스당(Per-Instance)인지 지정 | D3D11_INPUT_PER_VERTEX_DATA or D3D11_INPUT_PER_INSTANCE_DATA |
InputLayout 생성 과정
정점(Vertex) 데이터 구조 정의
struct Vertex
{
Vector3 vPos; // 정점 위치 (X, Y, Z)
Vector4 vColor; // 정점 색상 (R, G, B, A)
// 여러 요소 추가 가능
//Vector2 vUV; // 정점 UV
//Vector3 vNormal // 정점 normal
};
InputLayout 생성
- Input Layout은
D3D11_INPUT_ELEMENT_DESC
배열을 사용하여 정의된다.
D3D11_INPUT_ELEMENT_DESC LayoutDesc[2] = {};
- 정점 속성을 설정한다.
// POSITION 속성
LayoutDesc[0].SemanticName = "POSITION"; // 쉐이더에서 사용하는 변수명
LayoutDesc[0].SemanticIndex = 0; // 여러 개의 같은 타입이 있을 경우 인덱스 지정
LayoutDesc[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; // float3(X, Y, Z)
LayoutDesc[0].InputSlot = 0; // 해당 데이터를 받을 버퍼 슬롯
LayoutDesc[0].AlignedByteOffset = 0; // 버퍼 내 위치 (0부터 시작)
LayoutDesc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; // 정점마다 다른 값
LayoutDesc[0].InstanceDataStepRate = 0; // 인스턴싱 안 함
// COLOR 속성
LayoutDesc[1].SemanticName = "COLOR"; // 쉐이더에서 사용하는 변수명
LayoutDesc[1].SemanticIndex = 0;
LayoutDesc[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; // float4(R, G, B, A)
LayoutDesc[1].InputSlot = 0;
LayoutDesc[1].AlignedByteOffset = 12; // 이전 속성(XYZ 12바이트) 이후 위치
LayoutDesc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
LayoutDesc[1].InstanceDataStepRate = 0;
InputLayout을 정의할 때 주의할 점
- SemanticName과 Shader에서 사용하는 변수명이 같아야 함.
- 예제에서는
"POSITION"
과"COLOR"
을 사용.
- 예제에서는
- Format은 속성의 데이터 타입과 일치해야 함.
- 예제에서는
float3(X, Y, Z)
→DXGI_FORMAT_R32G32B32_FLOAT
float4(R, G, B, A)
→DXGI_FORMAT_R32G32B32A32_FLOAT
- 예제에서는
- AlignedByteOffset을 정확히 설정해야 GPU가 데이터를 올바르게 읽을 수 있음.
- 위치(Position) 속성은 0바이트부터 시작.
- 색상(Color) 속성은 12바이트(X, Y, Z 이후)부터 시작.
InputLayout 생성 및 GPU에 적용
위에서 정의한 LayoutDesc
을 사용하여 InputLayout을 생성하고 GPU에 전달한다.
ComPtr<ID3D11InputLayout> Layout; // Input Layout 객체
_DEVICE->CreateInputLayout(LayoutDesc, 2,
VS_Blob->GetBufferPointer(),
VS_Blob->GetBufferSize(),
Layout.GetAddressOf())
LayoutDesc
배열을 사용하여 2개의 속성(Position, Color)을 설정.VS_Blob->GetBufferPointer()
→ 버텍스 쉐이더 코드에서 입력을 검사하여 Layout과 일치하는지 확인.
그래픽 파이프라인에 InputLayout 적용
렌더링을 수행하기 전에 Input Layout을 GPU에 바인딩해야 한다.
_CONTEXT->IASetInputLayout(Layout.Get());
- Input Assembler(IA) 단계에서 해당 Layout을 사용하도록 설정.
결론
- VertexShader가 정점 데이터를 올바르게 해석할 수 있도록 매핑
- 정점 속성(위치, 색상, UV, 법선 등)의 데이터 타입과 위치를 정의
- GPU가 VertexBuffer 데이터를 올바르게 읽을 수 있도록 설정
- 그래픽 파이프라인(Input Assembler 단계)에서 정점 데이터를 처리할 때 필수
InputLayout이 없으면 GPU는 정점 데이터의 구조를 인식할 수 없으며, Vertex Shader에서 올바른 입력을 받을 수 없다.
댓글남기기