그래픽스 모델링 (2) - 법선 벡터 (Surface Normal)

그래픽스

2020. 5. 9. 07:17

  • Vertex Array (정점 배열)에는 위치정보 외에도 많은 정보가 저장된다고 이전 글에서 설명했다.
  • 이번에는 Vertex Array (정점 배열)에 저장되는 데이터 중 하나인 Surface Normal에 대해 알아보자.

 

1. 삼각형 Normal (법선 벡터) 계산 방법

[그림] Surface Normal

  • 하나의 삼각형은 평면이고, 그 평면에 수직인 벡터를 Normal (법선 벡터)라고 한다. 
  • 꼭지점 세개를 p1, p2, p3라고 할 때, 1번 꼭지점과 2번 꼭지점을 잇고 이 것을 v1이라고 한다
  • 또, 1번꼭지점과 3번꼭지점을 잇고 이것을 v2라고 한다.
  • 이렇게 두가지 벡터가 주어질 때 v1 -> v2로 오른손 법칙을 적용한다. (쉽게 말해 외적한다는 의미이다)
  • 외적의 중요한 성질 중 하나인 입력 벡터들에 수직인 벡터가 만들어진다는 점인데, 두 변에 수직이면
  • 삼각형에도 수직인 벡터가 되는 것이 자명하다. 컴퓨터 그래픽스에서는 모든 Normal을 단위벡터로 표현한다.
  • 때문에 v1 x v2 (cross product)하고 그 것의 크기(norm)으로 나눠주면 Normal을 구할 수 있다.

 

2. 좌표의 순서에 따른 삼각형 Normal 변화

[그림] CW로 그려진 폴리곤 메쉬

  • 일반적으로 그래픽스에서는 삼각형의 좌표를 표현할 때 CCW (Counter - Clockwise, 반시계)로 표현한다.
  • 그러나 만약 좌표가 시계방향(CW, Clock-wise) 순서로 되어있으면 무슨일이 벌어질까?
  • CW 순서로 되어있으면, Cross Product, 즉 Surface Normal의 방향도 바뀌게 된다. 결론은 CW 순서으로
  • 놓으면 안된다라는 것이다. 보통 Normal은 물체 바깥으로 향하게 하는 것이 대부분의 관례이기 때문이다.

]그림] 실제 구 예시

  • 구에서 만약 prq vs pqr을 골라야한다면 pqr이 반시계방향(CCW)이기 때문에 t1을 0,1,2와 같이 배치해야하고
  • t2도 spq vs sqp중 골라야한다면 sqp가 반시계방향 (CCW)이기 때문에 t2를 3,1,0과 같이 배치시켜야한다.
  • 시작점은 중요하지 않다. 만약 t2에서 q를 시작점으로 잡으면 qps 순서로 놓기만 하면 된다.

 

3. 정점 Normal 

[그림] 정점 Normal

  • 그리고 OpenGL과 같은 엔진들에서 각 정점은 그 정점에서 바깥방향으로 뻗는 정점 Normal 정보를 갖는다.
  • 이 정보들은 Vertex 배열에 위치정보(x, y, z)와 함께 들어있다. 그런데 원래 각 정점의 법선벡터를 구하려면
  • 구의 정보가 필요하다. 구의 방정식으로 해당 정점에서의 tangent plane의 법선벡터를 계산해야하는데,
  • 그렇게 하지않고 삼각형 법선벡터가 있으니, 해당 정점을 공유하는 모든 삼각형 벡터의 평균을 내고,
  • 그 평균의 사이즈로 나눠주면 (유닛벡터) 정점의 Normal을 매우 쉽게 구할 수 있다. 그래서 보통
  • 이런 방식으로 정점 Nomal을 구한다. Vertex Normal은 Vertex 배열이 반드시 가져야하는 필수 요소이다.

 

4. Import와 Export

  • 만약 Max와 같은 모델링 도구로 메쉬를 만들고, 그 메쉬를 유니티나 OpenGL같은 곳에서 사용하려면
  • Max에서 모델링 파일을 Export해서 꺼낸뒤에, 유니티, OpenGL에 Import 시키는 방식으로 운용한다.
  • 보통 이 때, 모델링 파일로 가장 많이 쓰이는 형식이 .obj파일인데, 어떤형식으로 저장되는지 알아보자.

 

5. Export시 obj파일의 좌표 및 법선벡터 저장 방식 

[그림] obj 파일 내부

  • obj파일은 실제로는 위와같이 저장되어있다. 정점이 26개, 삼각형이 48개 있는 구를 생각해보자.
  • v 옆에 세개의 숫자 정보는 Vertex의 좌표이고, vn 옆에 세개의 숫자정보는 Vertex Normal (법선벡터)이
  • 저장되어 있는 것이다. 이 경우는 구이기 때문에 모든 정점이 자신의 고유한 Normal을 갖게 되지만,

[그림] 육면체의 경우는?

  • 위와 같은 육면체 오브젝트라면 위의 두점은 위치정보 (x, y, z)는 서로 다르지만, 법선벡터는 동일하다.
  • 이런 경우에는 법선벡터를 중복되게 저장하지 않고, 고유한 법선벡터는 딱 하나만 vn 벡터에 저장한다.
  • f 옆에 정보들은 face 정보, 즉 삼각형 정보인데, 세개의 Vertex와 세개의 Vertex Normal로 정의 되어있다.
  • 2//2라고 하면 2번째 Vertex와 2번째 Normal을 말하며, 3//4라고 하면 3번째 Vertex와 4번째 Normal을 의미함.

 

6. Import시 obj파일을 로드하는 방법

[그림] obj 파일 import시 로딩방식

  • 각 삼각형의 꼭지점이 가진 Vertex 위치와 Normal 정보를 로드하고나서, 이 Vertex Array의 좌표를
  • 참조할 Index Array를 생성한다. 유니티나 OpenGL에서 삼각형을 그릴 때 Index Array를 참조하는데
  • Index Array를 세개씩 끊어서 읽어서 삼각형을 만들고 최종적으로 그 삼각형을 모두 조합하여
  • 하나의 메쉬 오브젝트를 화면에 그릴 수 있는 것이다.

 

7. Reference