[DirectX12] #Part 2 - Direct 3D 기초
"DirectX12를 이용한 3D 게임 프로그래밍 입문" 서적의 Part 2, "Direct3D의 기초"에 해당하는 내용입니다.
현재, 게임 개발에 입문하여 기초지식을 습득하여 기록하기 위함이며, 개념 이해와 예제코드 작성을 진행.
엘리어싱 효과
모니터의 해상도를 결정하는 픽셀들은 무한히 작지 않습니다, 따라서 모니터 화면에 임의의 선을 끊김 혹은 계단 현상없이 출력하는 것은 불가능합니다. 선을 픽셀 배열들로 근사하다 보면 생기는 현상이죠. 위 그림과 같이 삼각형 변에서도 이와 비슷한 엘리어싱 효과가 나타납니다.
1. 초과표본화(Supersampling)
단순히, 모니터의 해상도를 키워, 픽셀의 크기를 줄이면 해결할 수 있는 문제입니다. 하지만, 해상도를 키울 수 없거나, 한계가 존재할때 우리는 엘리어싱 제거 기법을 적용합니다. 그 중 하나가 초과 표본화(Supersampling)입니다. 우선, 초과 표본화란 후면 버퍼와 깊이 버퍼를 4배 키워, 해상도를 높입니다. 화면에 제시할 3차원 프레임을 후면 버퍼에 렌더링합니다. 화면에 제시하기위해 전면 버퍼에 담는 과정에서 원래 크기의 버퍼로 "환원"합니다. 이러한 환원 공정은 하양표본화라고도 하며, 4픽셀 블록 4개 생상의 평균값을 해당 1픽셀의 최종 색상으로 사용하게 되죠. 결과적으로, 초과표본화란 화면 해상도를 소프트웨어 레벨에서 증가하는 것이라 할 수 있겠죠. 하지만! 픽셀 처리량이 늘어남에 따라 메모리 소비량도 4배 증가하여, 비용이 높습니다! 따라서, 우리는 아래 설명할 다중표본화(Multisampling) 기법을 절충안으로 사용합니다.
2. 다중표본화(Multisampling)
4X 다중표본화(1 픽셀당 부분 픽셀 4개)의 경우, 위에서 설명한 초과표본화와 같이 화면해상도 4배 크기의 후면 버퍼와 깊이 버퍼를 사용합니다. 하지만, 4개의 부분픽셀들을 각각 계산하지 않고, 중심 픽셀 1개만 계산하고, 계산된 색상과 주변 부분 픽셀들의 가시성과 포괄도를 고려하여 최종 색상을 결정합니다. 초과표본화와 비교하자면, 다중표본화는 비교적 비용이 상당히 낮지만, 덜 정확한 결과를 낸다고 볼 수 있습니다.
Direct3D의 다중표본화
typedef struct DXGI_SAMPLE_DESC
{
UINT Count;
UINT Quality;
}DXGI_SAMPLE_DESC;
다중표본화를 위해 Direct3D는 DXGI_SAMPLE_DESC"라는 구조체를 정의해야합니다. 이 구조체는 위처럼 2개의 멤버를 가집니다. "Count"는 픽셀당 추출할 표본의 수, 그리고 Quality 멤버는 원하는 품질 수준을 의미합니다. 이때, 품질 수준은 텍스처 형식과 픽셀당 표본 개수(Count)에 의존합니다. 주어진 텍스처 형식과 표본 개수의 조합에 대한 품질 수준들은 ID3D12Device::CheckFeatureSupport 메서드로 알 수 있습니다.
// 구조체 정의
typedef struct D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS{
DXGI_FORMAT Format;
UINT SampleCount;
D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG FLAGS;
UINT NumQualityLevels;
}D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS;
// 위 구조체를 채워넣는 코드
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msQualityLevels;
msQualityLevels.Format = mBackBufferFormat;
msQualityLevels.SampleCount = 4; //표본의 개수
msQualityLevels.Flags = D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;
msQualityLevels.NumQualityLevels = 0;
// 품질 수준을 체크합니다
ThrowIfFailed(md3Device->CheckFeatureSupport(
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS,
&msQualityLevels,
sizeof(msQualityLevels)
));
이때, "msQualityLevels"에 저장된 구조체를 입력과 출력에 동시에 사용됩니다. 아래 메서드를 통해 "msQualityLevels"에 저장된 구조체에서 텍스처 형식(msQualityLevels.Format)과 표본 개수(msQualityLevels.Count)를 읽고, 그에 해당하는 품질 수준의 개수를 msQualityLevels.NumQualityLevels 멤버에 설정하죠. 따라서, 주어진 텍스처 형식과 표본 개수의 조합에 대해 유효한 품질 수준의 개수는 0 ~ NumQualityLevels-1 까지입니다.
엘리어싱 효과를 제거하기 위해 DirectX12에서 다중표본화를 사용합니다
'게임개발 > DirectX12' 카테고리의 다른 글
[DirectX12]#Part2 - Direct3D의 기초_기능 지원 점검 (0) | 2021.12.28 |
---|---|
[DirectX12]#Part2 - Direct3D의 기초_DXGI (0) | 2021.12.28 |
[DirectX12]#Part2 - Direct3D의 기초_자원과 서술자 (0) | 2021.12.27 |
[DirectX12]#Part2 - Direct3D의 기초_교환 사슬 & 깊이 버퍼링 (0) | 2021.12.24 |
[DirectX12]#Part2 - Direct3D의 기초_텍스처 (0) | 2021.12.23 |