triangles[0]
을 NDC 공간에 맞도록 잘라내는 삼각형 클리핑(triangle clipping)을 진행합니다. Triangle
의 정점(Vertex)들은 모두 클립 좌표(clip coordinate)이어야 하는데, 선형 결합(linear combination)을 하기 위해서는 선분(segment)이 일정한 기울기를 가진 직선의 형태이어야 하기 때문입니다.
Renderer.clipTriangle0()
이 잘라낸 Triangle
들은 triangles
에 저장되며, 그려야할 삼각형의 갯수를 돌려줍니다. triangles
은 충분한 크기로 할당되었다고 생각하는 Triangle[]
입니다.
Renderer.clipTriangle0(triangles);
triangles
삼각형들을 담을 배열을 나타내는 Triangle[]
. triangles[0]
에는 원본 삼각형이 담겨있어야 하며, 삼각형 클리핑(triangle clipping)을 적용한 결과를 배열에 차례대로 담습니다. 배열의 크기 triangles.length
는 최소 30
이상이어야 하며, 배열의 원소 Triangle 들은 미리 할당되어 있어야 합니다:
const triangles = new Array(30);
for(let i=0; i<30; ++i) {
triangles[i] = new Triangle(new Vertex(), new Vertex(), new Vertex());
}
그려야할 삼각형 Triangle 들의 갯수를 나타내는 number
. 예를 들어 결과가 3
이라면, triangles[0], triangles[1], triangles[2]
를 그려야 한다는 의미입니다:
Camera.perspective() ⇒ Camera.clipToNDC() 를 적용하고 나면, 삼각형(Triangle)은 NDC 공간에 있게 됩니다. 여기서 Camera.ndcToViewport() 를 적용한다면, 삼각형은 카메라의 영역에 가득찰 정도로 커지게 될 겁니다(카메라의 해상도를 곱해주었으니까요).
예를 들어 NDC 좌표인 점 $\vec{p_{ndc}} = (1, 1, 1, 1)$ 이 있고, 카메라의 해상도가 $(480, 270)$ 이라고 해볼까요? Camera.ndcToViewport() 를 적용하면 $\vec{p} = (480, 270, 1, 1)$ 이 되겠군요. 그렇다면 NDC 공간의 영역을 벗어났다면 어떻게 될까요?
NDC 좌표인 점 $\vec{p_{ndc}} = (1.5,\; 1, 1, 1)$ 이 있고, 카메라의 해상도 $(480, 270)$ 을 곱해주었을때 $\vec{p} = (720, 270, 1, 1)$ 이 되겠네요. 만약 이 점을 Renderer.setPixel() 에 주었다면, 픽셀 배열(pixelBuffer)의 인덱스가 잘못되어 RangeError
예외를 발생시킬겁니다.
물론 가장 큰 문제는 근평면(near plane)을 벗어난 점이 있는 경우입니다. Camera.perspective() 의 원리 때문에, 근평면을 벗어나게 되면 삼각형의 상하가 뒤집혀버릴 수도 있기 때문이죠.
먼저 어째서 클립 좌표(clip coordinate)를 사용해야 되는지, 선분을 어떻게 자르는지에 대해서는 testRight(), testLeft(), testTop(), testBottom(), testFar(), testNear() 와 clipRight(), clipLeft(), clipTop(), clipBottom(), clipNear(), clipFar() 를 읽어보시길 바랍니다.