그래픽스

컴퓨터 그래픽스 - 깊이 버퍼 (Z-Buffer, Depth-Buffer)

오의현 2024. 4. 25. 19:16

깊이 버퍼

 

깊이 버퍼란, 화면을 기준으로 얼마나 깊이있는가를 저장하는 버퍼이다.

우리가, 두 물체를 앞에서 보았을 때 위의 그림과 같이 놓여있다고 해보자.

두 물체는 언뜻 보기엔, 나란하게 놓여있는 것처럼 보인다. 하지만, 시야를 y축기준으로 90도 돌려서 물체를 좌측에서 관측해보자.

 

옆으로 돌려서 좌측에서 두 물체를 관측했더니, A가 B보다 더 뒤에 있음을 알 수 있었다.

즉, 현재 그래프에선 z값이 A가 더 큰 상황인 것이다.

 

정면에서 볼 때엔, A와 B가 나란하게 옆에 놓여있는 것처럼 보였지만 실제로는 A가 B보다 뒤에 존재했던 것이다.

 

이처럼, 각 물체는 z값을 기준으로 화면으로부터 얼마나 더 뒤에있는가를 수치로써 가지게 된다.

이 z값을 이용하여 물체가 얼마나 더 뒤에 있는지를 기록하는 버퍼를 깊이버퍼라고 한다.

 

그렇다면, 깊이버퍼가 왜 필요할까?

 

아래 그림처럼 두 물체가 겹쳐있다고 가정해보자. 

우리가 생각으로는 뒤에 있는 물체가 앞에 있는 물체에 의해 가려져야 하는게 당연한 결과이다.

그런데, 실제로는 그렇지 않다. 컴퓨터는 그저 물체의 색을 픽셀 배열에 찍어낼 뿐이기 때문에, 그리는 순서가 달라지면 위 그림과 같은 상황을 항상 보장하지 못한다.

 

만약, 초록색 구를 먼저 그리고 노란색 구를 그렸다면?

이런식으로 픽셀의 색을 덮어씌워버리면서, 실제로는 뒤에 있어야 할 물체가 더 앞에 있는 것처럼 렌더링이 되어버린다.

 

이러한 상황을 해결하기 위해 사용되는 것이 깊이버퍼이다.

한 픽셀에 이미 색이 칠해졌는데 그 위에 새로 색을 칠하게 될 때, 두 물체의 깊이버퍼를 비교하여 깊이버퍼의 값이 더 작은 쪽으로 픽셀을 칠하게 되는 것이다.

 

깊이버퍼를 사용하여 깊이체크를 하면, 물체를 렌더링하는 순서와 상관 없이 더 뒤에 있는 물체는 뒤에 있는 것처럼 그릴 수 있게 된다.

 

Z-Fighting

 

두물체가 겹칠 때, 깊이버퍼를 이용하여 물체중 앞에 칠해야 할 색을 구분한다고 하였다. 근데 만약 두 물체의 깊이버퍼 값이 동일하다면? 컴퓨터의 실수오차 문제로 실제로는 Z값이 다르게 계산된다 하더라도 컴퓨터에선 동일한 값으로 판단하는 경우도 있다. 혹은 실제로 Z값이 동일할 수도 있다. 이러한 경우에는 어떤 물체를 더 앞에 그려야하는지 판단하는데 오류가 발생해 앞뒤가 계속 바뀌면서 겹치는 부분이 깜빡깜빡거리는 상황이 발생한다. 이를 Z-Fighting라고 한다. 

 

그러니, 물체를 배치할 때엔 너무 겹쳐서 배치하지 않는 것이 좋다. 하지만, 어쩔 수 없이 겹쳐야 하는 경우도 있는데, 해결법은 카메라의 near, far 수치를 조정하는 방법이 가장 대표적이다.

 

깊이 버퍼 활용

 

깊이버퍼는 더 앞에 그려져야 할 물체를 판단하기 위한 목적말고도 사용되는 곳이 많다. 대표적으로 그림자가 있다.

그림자를 그리기 위해선, 광원으로부터 가려진 픽셀을 찾아내야 한다. 

 

그림을 보면, 광원이 물체를 비추고 그 물체의 뒤에 가려져 있어서 빛이 닿지 않는 바닥에 그림자가 지는 것을 볼 수 있다.

이 때, 그림자가 그려져야 할 부분은 광원 입장에선 물체보다 더 깊은 곳(안쪽)에 있는 픽셀이라고 판단할 수 있고 이를 깊이 버퍼에 저장하여 활용할 수 있다.