- Vertex Array (정점 배열)에는 위치정보 외에도 많은 정보가 저장된다고 이전 글에서 설명했다.
- 이번에는 Vertex Array (정점 배열)에 저장되는 데이터 중 하나인 Surface Normal에 대해 알아보자.
1. 삼각형 Normal (법선 벡터) 계산 방법
- 하나의 삼각형은 평면이고, 그 평면에 수직인 벡터를 Normal (법선 벡터)라고 한다.
- 꼭지점 세개를 p1, p2, p3라고 할 때, 1번 꼭지점과 2번 꼭지점을 잇고 이 것을 v1이라고 한다
- 또, 1번꼭지점과 3번꼭지점을 잇고 이것을 v2라고 한다.
- 이렇게 두가지 벡터가 주어질 때 v1 -> v2로 오른손 법칙을 적용한다. (쉽게 말해 외적한다는 의미이다)
- 외적의 중요한 성질 중 하나인 입력 벡터들에 수직인 벡터가 만들어진다는 점인데, 두 변에 수직이면
- 삼각형에도 수직인 벡터가 되는 것이 자명하다. 컴퓨터 그래픽스에서는 모든 Normal을 단위벡터로 표현한다.
- 때문에 v1 x v2 (cross product)하고 그 것의 크기(norm)으로 나눠주면 Normal을 구할 수 있다.
2. 좌표의 순서에 따른 삼각형 Normal 변화
- 일반적으로 그래픽스에서는 삼각형의 좌표를 표현할 때 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
- 그리고 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파일은 실제로는 위와같이 저장되어있다. 정점이 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파일을 로드하는 방법
- 각 삼각형의 꼭지점이 가진 Vertex 위치와 Normal 정보를 로드하고나서, 이 Vertex Array의 좌표를
- 참조할 Index Array를 생성한다. 유니티나 OpenGL에서 삼각형을 그릴 때 Index Array를 참조하는데
- Index Array를 세개씩 끊어서 읽어서 삼각형을 만들고 최종적으로 그 삼각형을 모두 조합하여
- 하나의 메쉬 오브젝트를 화면에 그릴 수 있는 것이다.
7. Reference
'그래픽스' 카테고리의 다른 글
그래픽스 모델링 (1) - 폴리곤 메쉬 (Polygon Mesh) (1) | 2020.05.09 |
---|---|
그래픽스를 위한 수학 개요 (0) | 2020.04.20 |
컴퓨터 그래픽스 개요 (0) | 2020.04.20 |