본문 바로가기

예전/3D

DirectX11 초기화

1. Swap Chain


화면이 깜박거리는 현상을 방지하기위해 double buffering을 한다. 

이를 Direct3D 에서 하기 위해 IDXGISwapChain이라는 인터페이스를 지원한다. 


이 인터페이스는 Front Buffer Texture, Back Buffer Texture, 

버퍼의 크기를 변경하겠다는 IDXGISwapChain::ResizeBuffers 함수와 

버퍼의 Present를 위한 IDXGISwapChain::Present 가 있다.



2. 텍스쳐 자원 뷰


렌더링 파이프라인에는 텍스쳐를 binding 할 수 있는 여러 stage가 있다.

흔히 두개로 나뉘는데,


텍스처를 렌더 대상으로 묶는 것 ( Direct3D가 텍스처에 렌더링 하는 경우 ) 과

셰이더 자원으로 묶는 것 ( 셰이더 안에서 텍스쳐를 추출하는 경우 ) 이다. 


이 두가지 용도의 텍스처를 생성할 때는 텍스쳐를 묶을 bind flag를 사용한다.


D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE 


그런데 텍스처 자원이 파이프라인의 단계에서 직접 binding되는 것은 아니다. 실제로는 텍스처가 연관된 뷰를 파이프라인 단계에 묵는다.


 [? 뭔소리야]


Direct3D 에서 텍스처를 사용하려면 텍스처 초기화시 그 텍스쳐의 resource view를 생성해야 한다. 


따라서 텍스처를 렌더 대상과 셰이더 자원으로 사용하는 예제를 위해서는 2개의 뷰를 생성해야한다. 


하나는 렌더 대상 뷰이고, 하나는 셰이다 자원 뷰이다.


ID3D11RenderTargetView, ID3D11ShaderResourceView 



resource view들은 본질적으로 두가지 일을 한다. 


하나는 Direct3D 에게 자원의 사용방식 ( 즉, 파이프라인의 어느 stage에 binding할 것인지) 


또 하나는 생성 시점에서 무형식을 지정한 자원 형식의 구체적인 형식을 결정하는 것이다. ???????????? 


무형식 자원의 경우 텍스처 원소를 한 파이프라인 단계에서는 부동 소수점 값으로 사용하고 다른 단계에서는 정수로써 사용하는 것이 가능함을 듯한다. 




어떤 자원에 대해 특정 뷰를 생성 할 수 잇으려면 애초에 그 자원을 생성할 때 해당 binding flag를 지정해야한다. 


예를 들어 D3D11_BIND_DEPTH_STENCIL flag를 지정하지 않고 생성한 자원에 대해서는 ID3D11DepthStencilView를 생성할 수 없다. 


무작정 생성을 시도하면 아래와 같은 degug error msg가 나타난다. 


D3D11: ERROR: ID3D11Device::CreateDepthStencilView: A DepthStencilView cannot be created of a Resource that did not specify D3D11_BIND_DEPTH_STENCIL.



3. multi sampling


직선을 픽셀로 나타낼때 화면에 깨져보이는 현상이 계단현상 aliasing이다. 


이를 제거하기위한 많은 antialiasing 기법이 있다.



초과 표본화 supersampling 

는 back buffer와 depth buffer를 화면 해상도보다 가로 2배, 세로 2배 총 4배를 크게 잡는다. 

3차원 장면을 4배 크기의 해상도에서 back buffer에 렌더링하고, 이미지를 화면에 present 할 때 back buffer를 원래 크기로 바꾼다.


하향 표준화 downsampling은 4픽셀의 블록의 네 색상의 평균을 최종 색상으로 사용한다. 간단히 말하면, 초과 표본화는 화면 해상도를 소프트웨어에서 증가하는 것이라 할 수 있다. 


초과표본화는 픽셀 처리량과 메모리 소비량이 4배라서 비용이 크다.

Direct3D는 다중 표본화 multi sampling 이라는 절충적인 aliasing 기법을 지원한다.



다중표본화는 일부 계산 결과를 부분 픽셀들 사이에서 공유하기 때문에 초과 표본화보다 비용이 적다. 

다중 표본화도 초과 표본화처럼 크기가 화면 해상도의 4배인 back buffer와 depth buffer를 사용한다. 그러나 다중 표본화는 이미지 색상을 각 부분 픽셀마다 계산하는 것이 아니라 픽셀당 한번만 계산하고 그 색상과 부분 픽셀들의 가시성(깊이, 스텐실 판정이 일어남) 과 포괄도 ( 부분픽셀의 다각형이 어느정도나 덮고 있는지를 뜻하는 값) 을 이요해 최종 색상을 결정한다. 




3-2. Direct3D 에서의 multi sampling


다중표본화를 위해서는 DXGI_SAMPLE_DESC 구조체를 채워야한다.


typedef struct DXGI_SAMPLE_DESC 

{

UINT Count;

UINT Quality;


} DXGI_SAMPLE_DESC, *LPDXGI_SAMPLE_DESC;



Count는 픽셀당 추출할 표본의 개수를 지정하고, Quality는 quality level을 지정한다. 

표본의 개수가 많을수록 그리고 품질 수준이 높을 수록 렌더링 비용이 증가하므로 비용과 속도사이의 절충선을 잘잡아야 한다.


품질 수준은 텍스처의 형식과 픽셀당 표본의 개수에 의존한다. 이를 알고 싶을 때는


HRESULT ID3D11Device::CheckMultisampleQualityLevels(DXGI_FORMAT Format,UINT SampleCount, UINT* pNumQualityLevels);


주어진 텍스처 형식과 표본 개수의 조합을 장치가 지원하지 않으면 이 함수는 0을 return 한다. 그 외의 경우에는 조합의 품질 수준 개수가 pNumQualityLevels 에 저장된다. 




4. 기능 수준


Direct3D 11 은 feature level 이 있다.


D3D_FEATURE_LEVEL 으로 대표되는 이 기능 수준은 사용해 Direct3D의 여러 버전에 대응된다. 




'예전 > 3D' 카테고리의 다른 글

Direct3D의 그리기 2. 정점 버퍼  (0) 2014.04.06
Direct3D의 그리기 1 정점의 입력과 배치  (0) 2014.04.01
[OPENGL] quaterinion  (0) 2013.09.24
플레이어 따라다니는 카메라  (0) 2013.02.27
SetSamplerState  (0) 2013.02.24