모델링에서는 polygon mesh를 통해 물체를 표현한다고 하였다.

 

그렇다면 왜 polygon을 사용해 물체를 표현하는것일까?

 

컴퓨터 그래픽스는 물체를 표현하는데 굉장히 많은 병렬 연산을 필요로 한다. 이때 구를 예시로 들자면 무수히 많은 점들을 필요로 하고 각 점들에 대해서 연산을 한다면 구 하나를 표현하는데도 엄청난 연산을 필요로 할 것이다. 이러한 물리적 한계를 뛰어넘기 위해 일종의 해상도를 낮추는 방식으로(근사적 표현 방식으로) polygon mesh를 사용한다.

 

구의 polygon mesh

 

위의 구를 표현하기 위해서 모든 점을 표현하는 것이 아니라, 일정한 갯수의 점을 다각형으로 잇는다. 이러한 방법을 polygon mesh라고 한다. 대체로 일반적인 다각형은 처리하지 않고 삼각형 또는 사각형 mesh로 처리한다. 또한 gpu가 폴리곤 메시 처리에 최적화 되어있기 때문에 다른 방식의 표현은 채택되기 어렵다.

 

여기서 이슈는 정점의 개수를 어느정도로 할 것인가가 굉장히 중요한 이슈가 된다. 정점의 갯수가 해상도가 되기 때문이다.

 

해상도를 늘리는 걸 refinement, 줄이는 것을 simplification이라고 한다. 위와 같은 LOD(Level Of Detail) 컨트롤은 그래픽스에서 상당히 중요한 주제 중 하나이다.

 

 

이러한 폴리곤 메시의 제작은 그래픽 디자이너가 3ds max등을 이용해 제작하는데 간단한 경우를 보면 다음과 같다.

폴리곤을 이용한 사람 얼굴 제작


그럼 실제로 polygon mesh가 컴퓨터 안에서 어떤 식으로 표현이 될까?

 

아래 그림을 보면 삼각형이 3개로 표현이 되고, 각각의 삼각형은 정점으로 정의 되어 있다. 세개의 꼭지점을 그대로 배열에 적어 놓는다.

모든 삼각형마다 정점을 배치를 하고, 3개씩 끊어서 읽으면 삼각형 정보를 모두 얻을 수 있다.

 

얼핏보면 굉장히 좋은 표현방식으로 보이지만 어떤 vertex의 경우 여러번 중복이 된다. 위 그림에선 (1,0)이 3개의 폴리곤에서 모두 사용되므로 세번이나 적어야 한다는 단점이 있다. 이러한 단점을 극복하기 위해서 표현하는 방식으로는 vertex와 index를 분리하는 방법이 있다.

정점을 중복 없이 나열하는 방법이다.

vertex array와 index array를 따로 만들어서, 위와 같은 적은 데이터로도 표현할 수 있게 된다.

사실 vertex array의 한 cell 이 엄청나게 크다. 실제로 vertex array로 중복 공간을 차지하는 비율이 index array가 중복 공간을 차지하는 비율보다 크다. 그렇기 때문에 위와 같은 방법을 써야 한다.


Surface normal

다음으로 Surface normal을 보자. vertex array에는 position 정보 말고 여러가지 정보가 들어간다. 그중 하나가 normal이고 우리 말로는 법선이라고 한다. 삼각형의 normal은 좌표를 알고있을 때 외적(벡터곱)을 통해 간단하게 계산할 수 있다.

 

삼각형의 꼭지점이 <p1, p2, p3> 라고 주어진다면,

<p1, p2, p3>

꼭지점을 이어서 v1, v2 벡터를 구한 후, 오른손 법칙으로 외적(v1 x v2)을 하면, 삼각형의 normal을 쉽게 구할 수 있다. 그런데 컴퓨터 그래픽스에서 모든 normal을 길이가 1인 unit vector로 표현하기 때문에 normalization 과정을 거친다. 

 

 

그런데 삼각형의 꼭지점이 <p1, p2, p3>가 아니라, <p1, p3, p2> 라고 주어진다면 시계방향으로 주어진 것이다.

<p1, p3, p2>

그러면 반대로 오른손 법칙을 적용해주면 되지만 방향은 반대가 된다. 물체 안쪽을 파고드는 normal이 구해진 것이다. 컴퓨터 그래픽스에서는 모든 normal이 물체 바깥으로 향하게 하는 것이 기본적인 관례이다.

 

따라서 시계 방향(p->r->q)이 아닌, 반시계 방향(p->q->r)으로 vertex array로 만들어준다.

그렇기 때문에 index array도 t2 삼각형은 [3, 1, 0] 순으로 저장한다. 시작점은 상관 없다.

 

표면의 normal은 여러 문제에서 중요한 역할을 하는데 대표적으로 빛의 표현등에서 중요하게 된다. 


Vertex normal

하지만 실제로 필요한것은 표면의 normal보다 정점에서의 normal이다.

vertex(정점) normal주변 삼각형들의 normal 평균으로 구할 수 있다.

 

 

아래 그림처럼 각 정점은 여러개의 삼각형에 의해서 공유가 되는데, 삼각형 normal은 쉽게 구할 수 있다.

그 정점을 공유하는 삼각형 normal의 평균을 구하면, 그 정점의 normal을 얻을 수 있다. 물론 nomalization은 해주어야 한다.

vertex normal 구하기

총 6개의 normal인 n1+n2+n3+n4+n5+n6 를 자기 자신으로 나누면 vertex normal을 구할 수 있다.

 

vertex normal은 vertex array가 반드시 가져야 할 정보이다.

 

즉 다음과 같은 정점 143개를 가진 물체(26개의 정점, 48개의 삼각형)를 표현할 수 있다.

vertex, vertex normal, face(삼각형 정보)

 

 

아래와 같이 vertex array(position, normal)와 index array로 나타낼 수 있다.

vertex array(position, normal), index array


Ref.

Introduction to Computer Graphics with OpenGL ES (J. Han)

'☘️ Computer Graphics > Fundamental' 카테고리의 다른 글

CG - Image Texturing  (0) 2022.07.18
CG - Rasterizer  (0) 2022.07.16
CG - Vertex Processing  (0) 2022.07.15
CG - Spaces and Transforms  (0) 2022.07.14
CG - Rendering pipeline 개요  (0) 2022.07.12
복사했습니다!