화면을 출력하는데 있어서 다양한 옵션으로 여러가지 결과를 나타내게 할 수 있다.
그 중 Depth, Stencil, Blending 이라는 요소들에 대해 알아보고 이들을 어떻게 조절하느냐에 따라 어떻게 렌더링이 되는지를 알아보도록 하자.
앞에 있는 물건이 뒤에 있는 물건을 가리는 것은 당연한 이치다. 그래픽스 오브젝트가 나란히 있다고 할 때, 바라보는 방향에 따라 한 물체가 다른 물체를 가릴 수 밖에 없다. 오브젝트는 각각의 위치좌표를 가지고 있는데, 그 중 Z 좌표가 카메라에서 멀고 가깝고를 결정한다.
따라서 우리는 이 Z값을 비교해서 가까이 있는 물체의 픽셀을 찍어내고, 멀리있는 물체의 픽셀은 찍지 않기로 한다.
화면마다 Depth buffer를 두고 모든 물체의 값을 받아 각 픽셀에서 찍혀질 물체의 Z값을 담는다. Z좌표는 0~1 사이의 값으로 나오는데, 작을수록 카메라에 가깝게 되고 이 때의 Z값이 Depth buffer에 담긴다.
glEnable(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glClearDepth(1.0f);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST); / glDisable(GL_DEPTH_TEST);
• 기능: 깊이 테스트를 활성화(glEnable) 또는 비활성화(glDisable)하는 함수
• 설명: 깊이 테스트는 렌더링할 때 각 픽셀의 깊이 값을 비교하여, 더 가까운 픽셀만 렌더링되게 한다. 만약 깊이 테스트를 비활성화하면, 그리려는 순서대로 렌더링이 이루어지며, 깊이 관계는 고려하지 않는다.
glDepthMask(GL_FALSE);
• 기능: 깊이 버퍼 쓰기를 비활성화하는 함수입니다. (GL_TRUE로 설정하면 쓰기를 다시 활성화할 수 있습니다.)
• 설명: 이 함수는 깊이 테스트는 활성화하되, 깊이 버퍼에 값을 쓰지 않도록 설정. 이 기능은 깊이 정보를 읽지만, 새로운 깊이 정보를 기록하지 않고자 할 때 유용한데, 투명한 객체를 렌더링할 때 주로 사용함.
glClearDepth(1.0f);
• 기능: 깊이 버퍼를 지울 때 사용할 깊이 값을 설정하는 함수.
• 설명: glClearDepth()는 깊이 버퍼를 glClear(GL_DEPTH_BUFFER_BIT)로 지울 때 채워질 값(기본 깊이 값)을 설정한다. 즉, 깊이 버퍼를 지울 때 모든 픽셀이 가장 먼 거리(1.0f)에 있다고 설정.
glDepthFunc(GL_LESS);
• 기능: 깊이 테스트에서 두 깊이 값을 비교하는 기준을 설정하는 함수.
• 설명: 이 함수는 렌더링할 픽셀의 깊이 값과 이미 렌더링된 픽셀의 깊이 값을 비교할 때 사용할 조건을 설정.
• GL_LESS는 새 픽셀이 더 가까울 때만 렌더링하라는 의미. 기본적으로 활용.
• 다른 비교 연산자로는 GL_GREATER, GL_EQUAL, GL_ALWAYS 등이 있으며, 각각 다른 조건을 설정할 수 있습니다.
일반적은 카메라의 시선은 perspective view 이다. 이 과정을 위해 perspective projection 을 사용하여 카메라공간으로 물체들이 이동되는데, 이 과정에서 동차좌표계를 (x, y, z, 1)로 맞춰주기 위해 Z값이 w로 나눠지는 계산을 진행하게 된다.
이렇게 원근감을 살리는 렌더링이 이루어지는데, 이에 따라 z의 값은 1/x 함수 형태로 분포하게 된다.
이로인해 함수 형태 상, 멀리있는 z값들 간에는 큰 차이가 보이지 않게 되고 컴퓨터 계산 상의 오차로 왜곡이 나타나게 된다.
Z-fighting은 컴퓨터 그래픽스에서 발생하는 시각적 아티팩트로, 두 개 이상의 오브젝트가 화면상에서 같은 깊이 값을 갖는 경우에 발생한다. 이로 인해 어떤 픽셀이 어떤 오브젝트에 속하는지 정확히 결정하지 못해, 오브젝트들이 겹치는 부분에서 픽셀이 깜빡거리거나 빗살무늬로 깨지는 결과가 나타나는 현상을 Z-fighting이라고 한다.
깊이 버퍼의 정밀도 부족: 깊이 버퍼가 충분히 많은 비트를 사용하지 않으면, 깊이 값의 차이를 충분히 정확하게 구별할 수 없게 된다.
카메라 근처/멀리 위치한 오브젝트들: 카메라의 near, far plane 설정이 너무 넓으면 깊이 버퍼의 정밀도가 멀리 있는 오브젝트 사이의 차이를 제대로 반영하지 못할 수 있다.
두 오브젝트의 동일한 위치: 두 오브젝트가 같은 위치에 있거나 매우 가깝게 겹쳐 있을 떄 Z-fighting이 자주 발생한다.