4장 부분이 내용과 코드가 많아서 나눠서 올리겠습니다.

 


[ Goal ] 

  1. 하드웨어와 Direct3D의 관계
  2. COM의 정의 및 역할
  3. 저장방식, 페이지 전환, 깊이 버퍼링, 다중표본화 같은 기초 그래픽 개념

1. 기본지식

  • Direct3D 12의 개요
    • Direct3D 는 GPU를 제어하고 프로그래밍 하는 저수준 API ( application programming inerface )
      • 저수준일수록 GPU와 가깝게 동작하므로 더욱 빠른 동작이 가능함.
      • 고수준 API는 디스플레이 생성하는 드라이버를 필요로 한다.\
    • Direct3D 12와 11의 차이점
      • 다중 스레드 지원 개선  
      • CPU부담 크게 줄임
      • 추상화가 줄고 개발자가 관리할게 많아져 어려웠지만 성능 개선

 

 


COM ( Component object Model )

  • DirectX의 프로그래밍 언어 독립성과 하위 호환성을 가능하게 하는 기술
    • 예를 들어 C++에서 만들고 Visual Basic 문서화된 컨트롤을 사용하는 JScript 애플리케이션을 작성할 수 있습니다.
  • COM 객체를 C++ 클래스로 간주하면 이해하기 쉽다.
  • 알아야 할 것 : COM 인터페이스를 가르키는 포인터 얻는 방법
    1. 함수 이용
    2. COM 인터페이스의 메서드를 이용
  • 생성시 new 키워드를 사용할 필요는 없지만 delete가 아닌 release 키워드를 통해 메모리 해제해야 한다.
    • Mirocsoft::WRL::ComPtr 클래스를 사용하면 자동으로 release 되어 사용자가 직접 release 할 필요가 없다.
      • WRL : Windows Runtime Library ( 사용하기 위해 wrl.h 헤더가 필요함 )
      • ComPtr은 쉽게 생각해 COM 객체를 위한 똑똑한 포인터라 할 수 있다.
      • ComPtr의 주요 메소드
        1. Get : COM 인터페이스를 가르키는 포인터 반환
        2. GetAddressOf : COM 인터페이스를 가르키는 포인터의 값( 주소 )를 반환
        3. Reset : ComPtr 인스턴스를 nullptr로 설정하고 바탕 COM 인터페이스의 참조 횟수를 1 감소
  • COM 인터페이스들은 이름이 대문자 I로 시작한다.

 

 

 


텍스처 형식

  • 텍스처는 행렬 ( 배열 ) 이라 생각하면 된다. 
  • 2차원 텍스처는 이미지 자료를 저장하는데 사용된다.
  • 사실 텍스처가 단순한 자료 배열은 아니다. ( 여러 방법에 사용됨 )
    • 텍스처에는 밉맵 수준들이 존재 할 수 있다.
    • GPU 필터링, 다중 표본화 등의 특별한 연산에도 사용된다.
  • 특정 자료형들만 저장할 수 있다.

 

 

 


교환 사슬과 페이지 전환

  • 용어 정리
    • 버퍼 : 주기억 장치와 주변장치 사이에서 데이터를 주고받을 때, 둘 사이의 전송속도 차이를 해결하기 위해 전송할 정보를 임시로 저장하는 고속 기억장치
  • 애니메이션이 껌벅이는 현상을 피하기 위한 과정 ( 이중 버퍼링 )
    1. 한 프레임 전체를 화면 바깥에서 그린다. ( 후면 버퍼 )
    2. 후면 버퍼가 완성이 되면 하나의 완전한 프레임으로써 화면이 표시한다. ( 후면 버퍼 -> 전면 버퍼 )
    3. 표시 되는동안 다시 화면 바깥에서 후면 버퍼를 준비한다.
  • 위와 같은 과정을 하기위해 계속 후면 버퍼를 생성하기에는 메모리 낭비이다.
  • 해결하기 위해서는 버퍼를 2개만 생성해두고 교차해 가며 화면에 표시하는 방법이다.
  • 즉 각 프레임마다 버퍼 포인터를 교차해 가면서 화면에 표시해 나가면 된다. ( 교환 사슬 생성 )
  • 만약 버퍼를 3개를 사용하면 삼중 버퍼링이라 하며 일반적으로는 버퍼 두개로 충분하다.

 

 

 


깊이 버퍼링

  • 용어 정리
    • 렌더링 : 컴퓨터 프로그램을 사용하여 모델 또는 이들을 모아놓은 장면인 씬 파일(scene file)로부터 영상을 만들어내는 과정
  • 각 물체의 깊이 정보를 담는다. ( 즉 거리를 계산한다. )
  • 이미지 자료를 담지 않는 텍스처의 한 예시
  • 픽셀의 값은 0~1 사이의 값으로 값이 클수록 멀리 있는 물체에 해당된다.
    • 예를 들어 1280 X 1024 해상도에서는 깊이 버퍼는 1280 X 1024 개의 원소들로 구성되어있다.
  • Direct3D는 깊이 버퍼링 또는 z-버퍼링이라 하는 기법을 사용한다.
  • 깊이 버퍼링을 통해 한 픽셀에 그려질 물체가 정해지는 과정 ( 렌더링 과정 )
    1. 깊이 버퍼값을 1.0 값으로 초기화하고 색상은 검은색 또는 흰색으로 초기화한다.
    2. 렌더링 순서대로 물체를 가져온다.
    3. 렌더링 할 물체의 깊이 버퍼 값이 기존의 깊이 버퍼값과 비교하여 깊이 판정을 수행한다.
      • 기존 깊이보다 낮으면 색과 깊이 버퍼값을 갱신한다.
      • 만약 크다면 갱신하지 않고 다음 렌더링 물체를 가져온다.
    4. 렌더링 할 물체 모두 가져와 갱신한다.
    5. 최종적으로는 가장 가까운 물체가 해당 픽셀을 차지하게 된다.
  • 깊이 버퍼는 하나의 텍스처 이므로 생성 시 특정한 자료형식을 지정할 필요가 있다.

 

 

 


자원과 서술자

  • 용어 정리
    • 바인딩 : 프로그램에 사용된 구성 요소의 실제 값 또는 프로퍼티를 결정짓는 행위를 의미한다. 예를 들어 함수를 호출하는 부분에서 실제 함수가 위치한 메모리를 연결하는 것도 바로 바인딩이다.
    • 파이프라인 : 파이프라인(영어: pipeline)은 한 데이터 처리 단계의 출력이 다음 단계의 입력으로 이어지는 형태로 연결된 구조를 가리킨다.
    • 서술자 ( Descriptor 또는 View ) : 하나의 리소스에 대한 정보를 담은 자료구조
  • 렌더링 과정에서 GPU는 자료를 기록하거나 자료를 읽어온다.
  • GPU가 그리기 명령을 수행하기 전에 먼저 해당 그리기 호출이 참조할 자원들을 렌더링 파이프라인에 바인드 해야한다.
  • 실제로 바인딩 되는것은 해당 자원을 참조하는 서술자이다. 실제 자원이 바인드 되는것이 아니다.
    • 이처럼 서술자들을 거치는 추가적인 간접층을 두는 이유는 GPU자원이라는 것이 범용적인 메모리 조각이기 때문이다. 즉 같은 자원들 서로 다른 렌더링 단계에서 사용 될 수 있기 때문이다.
    • 또한 자원의 일부 영역만 사용하거나 이 자원이 깊이로 사용되어야할지 렌더 대상으로 사용되어야 할지 GPU는 모르기 떄문에 이러한 정보를 서술자가 가지고 있다.
  • 서술자의 형식
    1. CBV/SRV/UAV : 순서대로 contant buffer( 상수 버퍼 ), shader resource ( 셰이더 자원 ), unorderd aceess view ( 순서 없는 접근 ) 을 가르킨다.
    2. RTV : render target ( 렌더 대상 ) 을 가르킨다.
    3. DSV : depth/stencil ( 깊이. 스텐실 ) 자원을 가르킨다.
    4. 표본 추출기 서술자는 텍스처 적용에 쓰이는 표본 추출기 자원을 서술한다.
  • DirectX SDK 문서화에는 무형식 자원은 유연성이 꼭 필요할 때에만 만들고 그렇지 않은 경우에는 형식을 완전히 지정해서 자원을 만들어야 한다고 서술한다.
    • 즉 어떤 용도이든 텍스처를 사용하기 위해서는 초기화 시점에 그 텍스처의 Resource View를 생성해야 한다.
  • Resource View의 역할
    1. DirectEd에게 Resource의 사용 방식 즉 PipeLine의 어떤 단계에서 바인드 할것인지 알려주는 것
    2. 생성 시점에서 Typeless Resource의 Tpye을 지정하는것

 

 

더보기

이 부분은 아직 이해가 잘 안되어서 책을 한번 다 읽어보고 다시 이해해봐야겠다.

 


다중표본화

  • 용어 정리
    • 엘리어싱 : 컴퓨터의 이미지 표현 방식이 아날로그 방식이 아닌 디지털 방식이기 떄문에 정확한 선을 나타낼때 계단처럼 끊어지는 현상이 나타난다. 이를 앨리어싱 현상이라 한다.
  • 앨리어싱 현상을 방지 하기 위해서 렌더링 과정에서 화면 해상도의 4배만큼으로 후면 버퍼의 크기를 결정한다.
  • 이후 색을 결정하고 전면 버퍼로 옮길때 화면 해상도의 크기로 다시 환원하는데 이를 하향 표본화라 한다.
  • 색을 결정하는 방법에 따라 그리고 계산하는 방법에 따라 2가지 기법이 나뉜다.
초과 표본화 다중 표본화
4배만큼 커진 후면 버퍼에서 각 픽셀마다 색의 값을 계산한다.

이후 하향 표본화 시 4개의 픽셀의 평균으로 해당 픽셀의 값을 결정한다.
4배만큼 커진 후면 버퍼에서 4개의 픽셀의 색을 하나의 색으로 통일시킨다.

이후 4개의 픽셀에 대한 가시성, 포괄도를 계산하여 최종 색상을 결정한다.
좀더 정확한 표현이 가능하지만 자원을 많이 쓴다.

각 픽셀별로 계산하기 때문에
덜 정확한 표현을 하지만 자원을 조금 쓴다.

4개의 픽셀에 대해 중심의 색으로 색을 결정하기 때문에

 

  • Direct3D 의 다주 표본화
    • 다중 표본화를 위해서는 DXGI_SAMPLE_DESC 라는 구조체를 적절히 채워야 한다.
typedef struct DXGI_SAMPLE_DESC
{
    UINT Count;            // 픽셀당 추출할 표본의 갯수
    UINT Quality;          // 품질 수준 ( 하드웨어 제조사마다 다를 수 있다. )
} DXGI_SAMPLE_DESC;

 

 

 


DXGI

  • 용어 정리
    • 디스플레이 어댑터 : 물리적인 하드웨어 장치 ( 예를 들어 그래픽 카드 )
    • DXGI : Direct3D와 함께 쓰이는 API.
  • DXGI는 여러 가지 공통적인 그래픽 기능성을 처리한다. 
    • 전체화면 모드 전환, 디스플레이 어댑터나 모니터, 지원되는 디스플레이 모드 같은 그래픽 시스템 정보의 열거 등
  • 초기화 과정에서 쓰이는 인터페이스
    1. IDXGIFactory : DXGI 객체들을 생성하는 메소드를 구현
      • 소프트웨어 어댑터 생성
      • 스왑체인 생성
      • 어댑터 열거
      • 전체화면으로 전환을 제어하는 윈도우 반환
      • WIndow Association 생성
    2. IDXGIAdapter : 컴퓨터의 하드웨어 및 소프트웨어 기능을 추상화 한것
      • 시스템이 그래픽 구성 요소에 대한 장치 인터페이스를 지원하는지 확인
      • 어댑터 출력을 열거
      • 어댑터의 DXGI 1.0 설명을 가져옴

 

더보기

이 부분은 아직 이해가 잘 안되어서 책을 한번 다 읽어보고 다시 이해해봐야겠다.

  •  

참고 : DirectX 12 를 이용한 3D 게임 프로그래밍 입문 / 한빛미디어

 

'독학 > DirectX' 카테고리의 다른 글

[ DirectX ] 기초 수학 3. 변환  (0) 2022.11.09
[ DirectX ] 기초 수학 2. 행렬 대수  (1) 2022.11.09
[ DirectX ] 기초 수학 1. 벡터 대수  (0) 2022.11.09

+ Recent posts