Rasterization: a Practical Implementation Visibility Problem the Depth Buffer Algorithm and Depth Interpolation
visibility problem을 해결하기 위해 삼각형을 Depth로 정렬하고 카메라와 더 가까운 삼각형을 그릴 수 있다. 하지만 이 방법은 충분하지 않다. 위 그림에서 보는 것처럼 삼각형이 서로 겹쳐 있으면 정확한 그림을 그릴 수 없다. (P3, P4)
이 문제를 해결하는 방법 중 하나는 depth buffer(z buffer)를 이용하는 것이다. depth buffer는 frame buffer와 같은 사이즈의 2d array이고 그 값은 depth를 갖는다. depth buffer를 만드는 방법은 아래와 같다.
1. depth buffer를 아주 큰 숫자로 채운다.
2. pixel이 overlap하는 삼각형 점의 depth를 구한다.
3. depth buffer의 값과 2에서 구한 depth를 비교한다.
4. 3에서 더 작은 숫자를 depth buffer에 저장하고 frame buffer를 현재 삼각형 점의 색으로 update한다.
이를 pseudo code로 표현해보자
float *depthBuffer = new float [imageWidth * imageHeight];
// Initialize depth-buffer with very large number
for (uint32_t y = 0; y < imageHeight; ++y)
for (uint32_t x = 0; x < imageWidth; ++x)
depthBuffer[y][x] = INFINITY;
for (each triangle in scene) {
// Project triangle vertices
...
// Compute 2D triangle bounding-box
...
for (uint32_t y = bbox.min.y; y <= bbox.max.y; ++y) {
for (uint32_t x = bbox.min.x; x <= bbox.max.x; ++x) {
if (pixelOverlapsTriangle(i + 0.5, j + 0.5) {
// Compute z-coordinate of the point on triangle surface
float z = computeDepth(...);
// Current point is closest than object stored in depth/frame-buffer
if (z < depthBuffer[y][x]) {
// Update depth-buffer with that depth
depthBuffer[y][x] = z;
frameBuffer[y][x] = triangleColor;
}
}
}
}
}
우리가 알고있는 z coordinate은 삼각형의 한 점에 불과하다. 값을 모르는 z coordinate을 구하기 위해 interpolation을 사용할 수 있다.
그러나 이전에 알아본 barycentric coordinate 함수를 이용하면 문제가 생긴다.
식은 문제없다. z coordinate은 vertices가 perspective division을 거치고나면 2d 삼각형에서 linear하게 펼쳐지지 않는것이 문제다.
위 그림처럼 벡터 V0P/V0V1 distance(0.666)이 canvas에서 distance 비율과 일치하지 않는다.
perspective division은 line은 보존하지만 distance는 보존 하지 못한다.
그렇다면 어떻게 P의 z coordinate을 찾을 수 있을까
댓글 영역