DirectX 11 Tutorial

DV·2023년 12월 13일

DirectX_2D

목록 보기
1/2

DirectX

DirectX는 Windows 프로그램에 고성능 하드웨어 가속 멀티미디어 지원을 제공하는 low-level의 응용 프로그래밍 인터페이스(APl) 집합이다.

[그래픽 하드웨어 연결]

  • DirectX는 응용 프로그램과 그래픽 하드웨어를 연결함
  • 사용자는 해당 그래픽 하드웨어가 DirectX 대응장치이기만 한다면, 하드웨어의 세부사항을 알 필요 없음
  • DirectX API를 이용해 그래픽 하드웨어에 접근하고, 물체를 렌더링하는 등의 작업 가능

[응용 분야 - 게임 개발]

  • 윈도우, 세가, 드림캐스트, 마이크로소프트 엑스박스 및 엑스박스 360 등을 위한 비디오 게임 개발에 많이 사용

Features of DirectX 11

Compute Shader

Compute Shader를 지원함으로써 (1)그래픽스 처리 이외에도 (2)데이터를 병렬처리할 수 있는 범용적인 프로세서로써 GPU를 활용할 수 있다.

  • Compute Shader는 DirectX Device를 통해 그래픽스 계열 shader와 resource를 공유하지만, 다른 shader와 직접 연결되진 않음
  • CPU: OS나 일반 어플리케이션 등을 실행하는 범용 프로세서
  • GPU: 그래픽스 처리에 특화된 전용 프로세서

//

DirectXGI


Direct3D 11은 기초적인 그래픽스 기능을 제공하는 DirectXGI 상에 구축되어 있다.

DirectXGI는 여러 그래픽 API에 공통인 그래픽 관련 작업들을 묶은 것으로, 커널 모드 드라이버 및 시스템 하드웨어와 통신한다. DXGI가 담당하는 영역에는 페이지 전환(스왑체인), 어댑터, 모니터, 디스플레이 모드 등의 그래픽 시스템 정보 등이 있다.

  • 간접 조작: DXGI 기능은 Direct3D 11로 접근하므로 어플리케이션 측에서 직접 조작하는 경우는 거의 없음
  • 직접 조작: gamma collection이나 출력 디스플레이 선택하는 등의 컨트롤이 필요할 경우

//

Swap Chain

스왑 체인은 프론트버퍼, 백 버퍼를 포함한 복수의 버퍼의 집합과 이들 사이의 전환 방식의 집합이다.
double buffering의 일종으로, 화면에 그려질 때 깜빡임(flicking)이나 찢어짐(tearing) 현상을 막기 위한 트릭이다.

DirectXGI의 기능으로써 제공된다.

  • 메모리 영역: 거의 항상 디스플레이 하위시스템의 메모리에 만들어짐
    (대부분 그래픽 카드이지만, 마더보드에도 구현 가능)
  • Presenting: 페이지를 전환하는 것, 즉 프론트 버퍼와 백 버퍼를 교환해서 화면 상에 백 버퍼를 그리는 행위

[복수의 버퍼 집합]
DirectX에서는 화면표시, 렌더링을 위해 Front Buffer와 Back Buffer를 사용한다.

  • Front Buffer: 디스플레이에 표시되는 화면 데이터를 가진 버퍼
  • Back Buffer : 다음 업데이트 내용 씀

[버퍼 전환]
렌더링이 끝났을 때 Front Buffer의 내용을 갱신한다.

  • 갱신 작업 중에는 back buffer에도 렌더링할 수 없음
  • 렌더링 퍼포먼스의 저하를 막기 위해 3개 이상의 버퍼를 준비하는 것도 가능

//

Device

DirectX 11 에서는 멀티 스레드 호환이 강화되었다.
DirectX 10의 Device가 11에서는 Device와 DeivceContext로 분할됐다.

  • Device: GPU 메모리 관리 & 리소스 생성
  • Device Context: GPU 렌더링 명령

[Device]
리소스 생성에 주로 사용한다. (렌더 타겟 뷰, 상태 변수의 생성 등등에 사용)
각 응용 프로그램에는 하나 이상의 장치가 필요하다. 대부분은 하나의 장치만 만든다.

  • ID3D11Device 인터페이스로 표시
  • D3D11CreateDevice로 디바이스를 생성하거나,
    D3D11CreateDeviceAndSwapChain으로 device와 swap chain을 동시에 생성

[Device Context]
device의 설정을 담당한다.
device에서 소유하는 resource를 사용해 파이프라인 상태를 설정하고, 렌더링 명령을 생성할 수 있다.

  • 생성된 자원들을 실제로 사용
  • 파이프라인 자체를 조작

예시로 상태 변수가 있다.
DepthStencilState 같은 상태 변수를 만들었다면 장치 컨텍스트에 적용시켜줘야 한다.

  • ID3D11DeviceContext 인터페이스로 표시
  • Imediate Context: device에 직접 렌더링, device에 1개만 존재
  • Deferred Context: main render thread 이외 worker thread에서 사용

//

Tessellation

Tessellation은 정밀도가 낮은 primitive data를 분할해, 보다 정밀한 primitive를 생성해 출력하는 기능이다.

[Tessellation OFF]

[Tessellation ON]

DirectX 11의 graphics pipeline에는 tessellation을 수행하는 1개 stage와 2개 shader(hull shader, domain shader)가 추가돼 realtime으로 tessellation을 수행할 수 있다.

  • primitive: DirectX에서 렌더링하는 도형의 최소단위
    (ex 점, 선, 삼각형 ...)

//

shader를 pipeline에 할당할때 shader code를 드라이버에 최적화할 수 있다.

  • 다양한 기능의 셰이더를 사용하기 위해 모든 기능을 갖춘 셰이더를 만들거나, 필요한 조합의 셰이더를 모두 만들 필요가 없어짐
  • 퍼포먼스, 리소스 관리 측면에서 이점

Basic Concept

Texture & Format

DirectX에서는 특정한 형식을 따르는 자료를 텍스처로 저장한다.

  • GPU 필터링, 다중표본화 등의 연산을 텍스쳐에 적용할 수 있음
  • format: 특정 포맷을 따르는 자료만 저장 가능

[DXGI_FORMAT 예시들]
텍스처의 자료형들은 DXGI_FORMAT이라는 열거형으로 저장된다.

DXGI_FORMAT_R32G32B32_FLOAT 	// red,green,blue 32bit float
DXGI_FORMAT_R16G16B16A16_UNORM 	// red,green,blue,alpha 16bit로 0~1사이 Normalized 값
DXGI_FORMAT_R32G32_UINT 		// red, green 32bit 정수
DXGI_FORMAT_R8G8B8A8_UNORM 		// red,green,blue,alpha 8 bit로 0~1값
DXGI_FORMAT_R8G8B8A8_SNORM 		// red,green,blue,alpha 8 bit로 -1~1 값
DXGI_FORMAT_R8G8B8A8_SINT 		// red,green,blue,alpha 8 bit로 -128~127 값
DXGI_FORMAT_R8G8B8A8_UINT 		// red,green,blue,alpha 8 bit로 0~255 값
  • 자료형에는 색상 정보 외에도 3차원 벡터와 같은 다양한 값을 담을 수 있음
DXGI_FORMAT_R8G8B8A8_TYPELESS 	// TYPELESS형
  • Typeless: 메모리만 확보해두고 해석 방식은 텍스쳐를 파이프라인에 묶을 때 결정

//

Resource

GPU가 어떤 일을 하기 위해선 shader 프로그램이 필요한데, shader에 넘겨주는 데이터를 Resource라고 한다.
Scene을 구성하는 기하 도형, 텍스처, 쉐이더 데이터가 모두 resource다.
resource는 buffer와 texture로 구성된다.

  • buffer resource: 1차원 배열(vertex buffer, index buffer 등)
  • texture resource: 이미지 형태 데이터

생명주기: 생성 -> 바인딩 -> 해지

  • Device가 생성
  • Device Context에 의해 pipeline binding
  • 다 쓰고 나서 Release() 함수로 resource 할당 해제

//

Resource View

resource view는 resource를 rendering pipeline에 binding해줄 수 있는 객체이다.
하나 이상의 graphics pipeline 단계에서 같은 resource에 접근할 때 resource view로 접근한다.

  • 여러 단계의 pipeline은 모두 하나의 같은 resource에 접근
  • 파이프라인 단계마다 resource를 할당하고 복사하지 않기 위해 view 사용

[예외]
resource는 view를 통해 pipeline에 binding하지만, view 없이 binding 가능한 resource도 있다.

  • Vertex Buffer
  • Index Buffer
  • Constant Buffer
  • Stream Output Buffer

[Resource view list]

  • Render Target View
  • Depth Stencil View
  • Shader Resource View
  • unordered access view (DirectX 11에서 추가)

//

Render Target View

resource view의 일종으로, Device의 back buffer에 binding되며 생성된다.
rendering pipeline의 출력 중 색상 값을 담는다.

[render target]
render target은 rendering 대상이다.
예를 들어, texture에 그린다면 texture가, window에 그린다면 back buffer가 render target이다.

[pipeline binding]
back buffer에 장면을 출력하려고 할 때 render target view를 파이프라인의 마지막 단계인 Output Merget State (OM)에 binding해야 한다.

  • back buffer를 pipeline에 직접 binding할 수 없음
  • 즉, pipeline에서 주는 정보가 back buffer로 바로 연결될 수 없음
  • pipeline -> render target view -> render target -> graphic device

[render target 설정]
render target 설정
render target을 설정할 때는 우선 render target view를 만들어준 후, Device Context에서 설정한다.

// backBuffer의 포인터로 render target view 생성
result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView);

// device context 설정
result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1,
        D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext);

// device context에 render target 설정
m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);

//

Depth Stencil View

rendering pipeline의 출력 중 depth와 stencil 값을 담는다.

OM에서 쓰이며, depth와 stencil 모두 output test에 쓰이므로 하나의 view로 묶는다.

[stencil]
스텐실 값은 두 개 이상 오브젝트가 겹쳤을 때 뭘 표시할지 나타낸다.
depth test와는 달리 앞-뒤 값으로 결정짓는 것이 아니라, 상황에 따른 stencil 값의 대소를 따져 앞-뒤를 계산한다

[code]

// OM setting 시 render target view와 depth stencil buffer를 함께 binding한다
m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView);

//

Basic Matrix

  • Perspective Projection Matrix 원근 투영 행렬: 3D 화면을 2D viewport space으로 변환
  • Orthographic Projection Matrix 직교 투영 행렬: UI와 같은 2D의 요소를 그리기 위해 사용
  • World Matrix: 오브젝트의 좌표를 3D 세계의 좌표로 변환, 3차원 공간에서의 회전/이동/크기 변환
  • View Matrix: 현재 장면에서 카메라 위치, 방향 계산

Graphics Pipeline

  • 📢필수📢 Input-Assembler (IA) :
    Vertext Shader에 필요한 데이터 전달
    리소스로부터 데이터를 읽어 들여 파이프라인에 데이터를 제공
    • Vertex Buffer 와 Index Buffer : 각 프리미티브 정보는 [ 버텍스 버퍼 ] 와 [ 인덱스 버퍼 ] 에 저장하여 파이프라인에 넘김
  • 📢필수📢 Vertext Shader :
    정점의 월드 변환과 뷰 변환 등 필요한 처리
  • 🔈선택🔈Hull Shader :
    Tesselation 기능 구성 shader.
    1~32 개의 [ 컨트롤 포인트 ] 를 입력받아,
    1~32개의 [컨트롤 포인트][배치 정수] [테셀레이션 계수] 를 출력
  • 🔈선택🔈Tessellator :
    Tesselation 기능 구성 stage.
    [ 쿼드 배치 ][ 삼각형 배치 ] [ 선 ]을 입력받아,
    보다 정밀한 다수의 [삼각형][선] [점]을 출력
  • 🔈선택🔈Domain Shader :
    Tesselation 기능 구성 shader.
    [ Hull Shader ] 와 Tessellator의 출력을 입력받아,
    배치 내의 각 vertex 좌표를 출력
  • 🔈선택🔈Geometry Shader :
    primitive data 1개를 입력받아, primitive의 변형이나 새로운 primitive의 생성을 수행한 후,
    0개 또는 1개 이상의 primitive data 출력
    • Stream Output : GS 나 VS 로부터 출력을 리소스 내의 버퍼에 씀
  • 📢디폴트📢 Rasterizer :
    각 정점을 보간해 pixel shader에서 사용할 pregment(픽셀별 정보) 생성
  • 📢필수📢 Pixel Shader :
    픽셀 데이터 1개를 입력받아, 텍스처 처리나 라이팅등을 수행한 후,
    픽셀 데이터 1개 출력
    • GPU 사용하는 주요 원인
    • 연산 횟수가 가장 많음 (단순 반복 작업)
  • 📢디폴트📢 Output-Merge(OM) 출력 병합기 :
    pixel shader에서 들어온 색상을 가지고 render target, depth, stencil 등을 고려해,
    어떤 걸 표시하고 표시하지 않을지 + 최종 렌더링 색 결정함
    • OM에서 계산된 픽셀 색상이 백 버퍼에 그려져서 화면에 보임

References
[1] DX11 Feature: https://blog.naver.com/sorkelf/40160740465
[2] DX Basic Concept: https://dev-nicitis.tistory.com/46
[3] Graphics Pipeline: https://learn.microsoft.com/ko-kr/windows/uwp/graphics-concepts/graphics-pipeline

0개의 댓글