비타Cpp

렌더링 파이프 라인 - IA(Input Assembler) Stage - Index 본문

DirectX12/메모

렌더링 파이프 라인 - IA(Input Assembler) Stage - Index

멍C 2021. 8. 1. 11:37

고형 3차원 물체(3D Primitive)의 기본 구축 요소는 삼각형이다. 예를 들어 삼각형 하나와 팔각형 하나를 Triangle List를 이용해서 구축한다고 할 때 다음은 이에 필요한 정점 배열이다.

//사각형
Vertex Quad[6] = 
{
v0, v1, v2,	//삼각형1
v0, v2, v3	//삼각형2
};

//팔각형
Vertex Octagon[24] =
{
v0, v1, v2,	//삼각형1
v0, v2, v3,	//삼각형2
v0, v3, v4,	//삼각형3
v0, v4, v5,	//삼각형4
v0, v5, v6,	//삼각형5
v0, v6, v7,	//삼각형6
v0, v7, v8,	//삼각형7
v0, v8, v1,	//삼각형8
};

정점 배열과 위 그림을 봤을때, 각 삼각형을 이루는 정점들 중 중복되는 정점들이 있고, 좀 더 복잡한 도형일수록 더 많은 정점이 중복된다는 점을 알 수 있다. 이러한 정점들의 중복은 별로 바람직하지가 않다. 그 이유는 크게 두 가지이다.

 

1. 메모리 요구량이 증가한다. (같은 정점 자료를 여러 번 저장할 필요가 있는가?)

2. 그래픽 하드웨어의 처리량이 증가한다. (같은 정점 자료를 여러번 Draw처리할 필요가 있는가?)

 

이러한 문제를 해결하는 방법은 Triangle Strip을 이용하는 방법이 있다. 이러면 정점 자체의 수가 줄어든다. 하지만 Triangle Strip형태는 기하학적으로 항상 가능한 형태가 아니다. 그래서 좀 더 범용적으로 해결할 수 있는 방안이 바로 "색인(Index)"을 사용 하는 것이다. 즉, 정점은 중복을 제외한 최소한의 개수만 생성하고, 그리는 순서만 index로 저장을 하는 방법이다. 이러면 사각형을 그릴 때 4개, 팔각형은 9개의 정점만 생성하면 충분하다.

 

//사각형
Vertex Quad[4] = { v0, v1, v2, v3 };

UINT IndexList_Quad[6] = 
{
0, 1, 2,	//삼각형1
0, 2, 3		//삼각형2
}

//팔각형
Vertex Octagon[9] = {v0, v1, v2, v3, v4, v5, v6, v7, v8}

UINT IndexList_Octagon[24]
{
0, 1, 2,	//삼각형1
0, 2, 3,	//삼각형2
0, 3, 4,	//삼각형3
0, 4, 5,	//삼각형4
0, 5, 6,	//삼각형5
0, 6, 7,	//삼각형6
0, 7, 8,	//삼각형7
0, 8, 1,	//삼각형8
};

이런 식으로 정점은 고유한 정점들만 따로 처리하고, 색인 목록을 이용하여 정점들을 조합해 삼각형을 형성한다. 이로써 중복 현상은 정점에서 일어나는게 아니라, 색인 쪽으로 옮겨간 것이 된다. 이는 앞에서 정점이 중복되는 것보다 훨씬 유리하다.

 

1. 색인은 그냥 정수값이므로 정점 구조체보다 적은 양의 메모리를 차지한다.

2. 정점들이 적절한 순서로 캐시에 저장된다면, 그래픽 하드웨어는 중복 정점들을 처리할 필요가 거의 없어진다.

Comments