Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

codingfarm

4. 다중표본화(multisampling) 본문

computer graphics/DX12 book

4. 다중표본화(multisampling)

scarecrow1992 2021. 1. 11. 21:32

모니터의 픽셀들이 무한히 작지는 않기 때문에, 모니터 화면에 임의의 선을 완벽하게 나타내는것은 불가능하다.

선을 픽셀들의 배열로 근사할 때 생기는, 계단현상이라고도 하는 앨리어싱(aliasing)의 예가 아래그림에 나타난다.

출처 : https://m.blog.naver.com/PostView.nhn?blogId=rkalstn2&logNo=30187944993&proxyReferer=https:%2F%2Fwww.google.com%2F

 

위와같은 픽셀을 제거하기 위한 앨리어싱 제거(antialiasing) 기법들이 존재하며, 이를 통해 아래와 같은 개선된 효과를 얻을 수 있다.

출처 : https://m.blog.naver.com/PostView.nhn?blogId=rkalstn2&logNo=30187944993&proxyReferer=https:%2F%2Fwww.google.com%2F

 

여기서 소개하는 안티애얼리싱 기법은 총 2가지가 있다.

 


초과 표본화(supersampling)

후면 버퍼와 깊이 버퍼를 화면 해상도보다 4배(가로, 세로 2배씩) 크게 잡는다. 후면 버퍼에 렌더링하고, 이미지를 화면에 제시할 때 후면 버퍼를 원래 크기의 버퍼로 환원(resolving) 한다. 하향표준화(downsampling) 이라고도 하는 이 공정은 4픽셀 블록의 네개색상의 평균을 최종 색상으로 사용한다.

하지만 이 방법은 메모리 소비량이 네배라서 비용이 크다.

 


다중표본화(multisampling)

성능과 효과에 동시타협할 수 있는 절충적인 방법으로 일부 계산 결과를 부분픽셀들 사이에서 공유하기 때문에 초과 표본화보다 비용이 적다. 4X 다중표본화의 경우 초과표본화처럼 화면 해상도의 4배인 후면 버퍼와 깊이 버퍼를 사용한다. 하지만 다중 표본화는 이미지 색상을 각 부분픽셀마다 계산하는것이 아니라 픽셀당 한 번만 계산하고, 그 색상ㅇ과 부분픽셀들의 가시성(이를 위해 부분 픽셀당 깊이, 스텐실 판정이 일어남)과 포괄도(부분픽셀을 다각형이 어느정도나 덮고 있는지를 뜻하는 값)를 이용해서 최종 색상을 결정한다.

폴리곤 외곽선이 지나가는 곳만 Sampling AA효과를 준다.
Coverage Sample-폴리곤 외곽선이 지나가는가를 테스트하는 샘플을 먼저 추출하고(추출된 샘플들이 모두 같은 면 위에 있지 않다면 이건 외곽선이 지나가는 점이다.) 외곽선이 지나갈경우 이 Coverage Sample의 위치에서 Color Sample을 추출하여 이들을 섞는다
만족할만한 화면품질과 성능저하로 오랫동안 AA기술의 표준으로 자리잡았다. 하지만 시간이 지나면서 AA에 대한 욕구증대에 반하여 기기성능이 제한(메모리와 연산량)되는 문제가 크게 다가옴에 따라 후처리AA들에게 많은 자리를 내주고 있다.

 

SSAA에 비하여 훌륭한 향상(엄청난 연산량 감소와 대비되는 작은 품질저하)을 보여주지만 이론상 폴리곤 외곽선만 적용되어 텍스쳐 내부에는 전혀 대응이 안된다. 또 SSAA보다 낫다고는 하지만 사용되는 메모리와 계산량은 상당하다.

 

Direct3D의 다중표본화

Multisampling을 위해서는 DXGI_SAMPLE_DESC라는 구조체를 채워야 한다.

typedef struct DXGI_SAMPLE_DESC {
    UINT Count;
    UINT Quality;
} DXGI_SAMPLE_DESC;

Count : 픽셀당 추출할 표본의 갯수

Quality : 원하는 품질 수준(quality level)

표본의 갯수(Count)가 많을수록, 품질 수준(Quality)이 높을수록 렌더링 비용도 증가하므로, 비용과 속도 사이의 절충선을 잘 잡아야 한다.

주어진 텍스처 형식과 표본 개수의 조합에 대한 품질 수준들의 개수를 알고 싶을때에는 ID3D12Device::CheckFeatureSupport 라는 메서드를 사용한다.

docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_feature_data_multisample_quality_levels

다음은 이 메서드를 사용하는 예 이다.

typedef struct D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS {
  DXGI_FORMAT                           Format;
  UINT                                  SampleCount;
  D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS 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_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONEl
msQualityLevels.NumQualityLevels = 0;
ThrowIfFailed(md3dDevice->CheckFeatureSupport(
    D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
    &msQualityLevels,
    sizeof(msQualityLevels)));

이 메서드의 2번째 매개변수가 입력과 출력의 역할을 담당한다.

이 메서드는 둘째 매개변수로 지정된 구조체에서 텍스처 형식과 표본 개수를 읽고, 그에 해당하는 품질 수준 개수르 그 구조체의 NumqualityLevels 멤버에 설정한다. 주어진 텍스처 형식과 표본 개수의 조합에 대해 유효한 품질 수준들은 0에서 NumQualityLevels-1 까지이다.

한 픽셀에서 추출할 수 있는 최대 표본 개수는 다음과 같이 정의된다.

#define D3D12_MAX_MULTISAMPLE_SAMPLE_COUNT	(32)

하지만 실제 응용에서는 다중표본화의 성능 및 메모리 비용을 합리적인 수준으로 유지하기 위해 표본을 4개나 8개만 추출하는 경우가 많다. 다중표본화를 사용하고 싶지 않으면 표본 갯수를 1로, 품질 수준을 0으로 설정하면 된다. 모든 dIRECT3d 12 대응장치는 모든 렌더 대상 형식에 대해 4x 다중표본화를 지원한다.

 

DXGI_SAMPLE_DESC 구조체는 교환 사슬 버퍼들과 깊이 버퍼 모두에 대해 채워야 한다. 후면 버퍼와 깊이 버퍼에 대한 다중표본화 설정은 동일해야 한다.

 

 

 

Comments