InputLayout

InputLayoutGPU가 정점 데이터를 어떻게 해석해야 하는지 정의하는 DirectX11의 필수적인 요소다.

Vertex Buffer에 저장된 데이터를 VertexShader가 올바르게 읽을 수 있도록 형식을 지정하는 역할이다.

InputLayout이 필요한 이유

DirectX11에서 버텍스 데이터를 GPU에 전달할 때, GPU는 정점의 구조를 자동으로 인식할 수 없다. 따라서, InputLayout을 사용하여 각 정점이 어떤 속성(Position, Color, Texture 등)을 포함하고 있는지 설명해야 한다.

  1. Vertex Buffer 데이터의 구조를 GPU에 전달 (어떤 데이터인지 알려줘야 함)
  2. Vertex Shader가 정점 데이터를 올바르게 읽을 수 있도록 설정
  3. 다양한 정점 데이터 구조를 지원하기 위해 필요 (예: 위치만 있는 정점, 텍스처 좌표가 포함된 정점 등)
  4. 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을 정의할 때 주의할 점

  1. SemanticNameShader에서 사용하는 변수명이 같아야 함.
    • 예제에서는 "POSITION""COLOR"을 사용.
  2. Format은 속성의 데이터 타입과 일치해야 함.
    • 예제에서는 float3(X, Y, Z)DXGI_FORMAT_R32G32B32_FLOAT
    • float4(R, G, B, A)DXGI_FORMAT_R32G32B32A32_FLOAT
  3. 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을 사용하도록 설정.

결론

  1. VertexShader가 정점 데이터를 올바르게 해석할 수 있도록 매핑
  2. 정점 속성(위치, 색상, UV, 법선 등)의 데이터 타입과 위치를 정의
  3. GPU가 VertexBuffer 데이터를 올바르게 읽을 수 있도록 설정
  4. 그래픽 파이프라인(Input Assembler 단계)에서 정점 데이터를 처리할 때 필수

InputLayout이 없으면 GPU는 정점 데이터의 구조를 인식할 수 없으며, Vertex Shader에서 올바른 입력을 받을 수 없다.

태그: ,

카테고리:

업데이트:

댓글남기기