2020년 7월 1일 수요일

DirectX - Depth Test, Blend Test

0. 문제

렌더링할때 만약 그림 그리듯이 덮어 씌운다고 생각하자. 적절한 렌더링 순서 없이는 작은 물체가 큰 물체에 가려지는 결과가 생길 것이다. 그러나 렌더링 순서를 정하는 것은 초당 화면 갱신을 매우 많이 해야하는 상황에선 비용이 너무 세다.

1. Depth Test

DepthBuffer 가 있어야 가능하다. 하는 일은, 가려진 물체는 렌더링 할 필요가 없으므로 z 값을 비교해서 각 위치당 가장 앞에 나온 것만 파이프라인을 통과하게 하고 나머지는 거르는 것. 이를 쓰면 간단히 문제가 해결된다.

DirectX 에서는 DepthStencilState 생성 시 DepthEnable 인자로 이를 적용할 수 있다. false 하면 그냥 z 값 무시하고 덮어쓰기를 한다.

2. Alpha Test

Depth Test 와 개념은 비슷하다. 일정 alpha 값 이하는 완전 투명, 일정 alpha 값 이상은 완전 불투명으로 처리하는 것이 Alpha Test 이다. 하지만 반투명을 처리할 수 없다.

DirectX 에서는 수동으로 해줘야 아마 하는 듯.

3. Alpha Blending 과 정렬 문제

Alpha Blending 은 자신의 alpha 값을 인자로 이미 그려진 색상과 자신의 색상을 보간한다. 하지만 이는 그리는 순서에 큰 의존을 받는다. 왜냐하면 물체가 겹칠 때 z 값에 따라 culling 하는 것이 alpha blending 보다 우선순위가 높기 때문이다. z 값이 작은(즉 앞에 있는) 반투명한 물체를 먼저 렌더링 하고, z 값이 큰 (즉 뒤에 있는) 물체를 겹쳐서 렌더링하면 후자는 z 값이 더 커서 보이지 않게 되어 원하는 결과를 얻지 못한다.

이 경우 해결책은 여러가지가 있지만 그 중 하나는 다음과 같다. alpha 값이 1이 아닌 경우 depth buffer 에 기입하지 않는다. alpha 값이 1인 opaque 들은 기존의 depth test 를 써서 렌더링 한다. 그리고 따로 빼둔 투명도가 있는 것들을 Sorting 해서 렌더링한다. 다만 내가 찾은 바로는 Direct X 내부에 이런 기능은 없다. 수작업 해야함.

BlendState 에서 BlendEnable 을 켜고 SrcBlend 를 D3D11_BLEND_SRC_ALPHA, DestBlend 를 D3D11_BLEND_INV_SRC_ALPHA 으로 해놓으면 기본적인 Alpha Blending 을 할 수 있다.


alpha blending 렌더링 순서 문제 x


alpha blending + 렌더링 순서 문제 o

4. Alpha To Coverage

위에서 투명색 처리가 되었을 부분이 검은 부분으로 나온것을 주목하자. 나뭇잎, 머리카락 등 사각형 이미지에 배경이 투명한 것들을 덕지덕지 발라놓을 경우, 투명한 배경이 그림을 다 가려버리면 곤란할 것이다. 이는 AlphaToCoverage 를 쓰면 해결이 된다. 아래 예시를 보면 이해가 될 것이다.

적용법은 자세하겐 모르겠다. 멀티 샘플링을 한다고 하는데 DirectX 11 을 보면 0.5 이하는 렌더링을 아얘 안하는 거 같고, 그 결과인 렌더링 하는 부분과 안하는 부분의 경계선을 멀티 샘플링으로 부드럽게 하는 것 같은데, 자세한 과정은 찾기가 힘들다.

DirectX 11 에서는 BlendState 생성 시 AlphaToCoverageEnable 에서 적용할 수 있다.


같은 soring problem 문제지만 검은색 배경이 없어진 모습

댓글 없음:

댓글 쓰기

List