물체의 z index 판단
3차원 공간의 물체들을 2차원 화면에 표현하려면 시선으로부터 물체들의 멀고 가까움을 알아야 합니다. 멀고 가까운 정도를 카메라 좌표계의 축의 의미에서 비롯한 물체의 z index 라 합니다. 물체의 z index 를 이용해 어떤 물체가 다른 물체에 가려 안보이는지 혹은 부분만 가려져 있는지를 판단할 수 있습니다.
이를 해결하기 위해 많은 알고리즘이 존재하지만 이 글에서는 그 중 가장 직관적이면서 많은 그래픽 엔진에서 사용하는 z 버퍼 알고리즘을 알아보겠습니다.
위 그림의 각각의 평면은 각각의 픽셀에 대해 z index 를 갖습니다. 카메라 좌표계에 대해 같은 , 좌표를 갖는 평면 의 지점 와 평면 의 지점 중 화면에 보이게 될 지점은 z index 가 낮은 입니다.
z index 를 사용하기 위해서는 (넓이 높이) 만큼의 크기를 가지는 이미지 버퍼와 같은 사이즈의 z 버퍼를 준비합니다. 할당된 z 버퍼는 모든 픽셀 값을 무한대로 초기화합니다. 이후 평면의 한 픽셀의 z index 를 구하고 대응하는 z 버퍼의 값과 비교해 더 작으면 z 버퍼의 값을 평면의 z index 값으로 덮어씁니다. 아래 그림은 모든 평면에 대해 반복하면서 z 버퍼의 값이 달라지는 과정을 보여주고 있습니다.
모든 평면에 대해 알고리즘의 순서는 다음과 같습니다.
for polygon of polygons
scanline polygon with z buffer
calculate polygon's current pixel's z index
if z index is smaller than z value in z buffer,
overwrite image buffer and z buffer with current polygon's color and z index respectively.
값 구하기
공간상의 평면들이 항상 카메라 좌표계의 평면과 평행하지는 않습니다. 따라서 평면의 각 지점에 대한 값을 직접 계산해야 합니다. 값의 계산식은 렌더링 시 물체의 투상법(projection) 에 따라 달라집니다. 이 글에서는 평행 투상(parallel projection) 과 원근 투상(perspective projection) 에 대해 각기 다른 계산식을 찾아보겠습니다.
아래 식은 평면의 방정식입니다.
평행 투상의 경우 카메라 좌표계 상 평면의 각 지점이 다음과 같이 투상됩니다.
스캔라인 채우기 알고리즘을 이용해 이미지 버퍼에 색을 입히는 과정은 모든 물체들이 2차원으로 투상된 이후입니다. 즉 평면의 한 지점의 투상된 2차원 벡터 만을 알 수 있습니다. 평행 투상에서는 주어진 정보 , 에 대해 아래와 같이 간단히 평면의 방정식을 이용해 값을 구할 수 있습니다.
원근 투상의 경우 카메라 좌표계 상 평면의 각 지점이 다음과 같이 투상됩니다.
따라서 스캔라인 과정에서 우리가 알 수 있는 정보는 , 입니다. , 라 하면 , 이므로 이를 평면의 방정식에 대입해 아래와 같이 정리할 수 있습니다.
계수 구하기
평면의 한 지점의 를 구하는 식을 알아보았습니다. 이번에는 평면의 방정식 에 대한 각각의 계수 , , , 를 구하는 방법을 알아보겠습니다. 평면의 방정식에서 계수 , , 는 평면의 법선 벡터(normal) 의 각각의 , , 성분을 의미합니다.
법선 벡터는 평면에 포함된 두 개의 벡터의 외적입니다. 두 개의 벡터는 평면의 세 꼭지점을 이용해 찾을 수 있습니다. 평면의 세 꼭지점을 , , 라 할 때 두 개의 벡터를 , 로 선택하면 법선벡터는 입니다.
계수 는 평면의 한 점 와 법선 벡터의 성분 , , 를 평면의 방정식에 대입해 찾습니다.