OBJ
OBJ
아래 이미지 어딘가 익숙하지 않은가?
3D 모델링에서 샘플로 자주 쓰이는 스탠포드 토끼(Stanford bunny)다.
요 근래에는 찾아보기 힘들지만 2D 그래픽스에서의 레나 포르센 포지션이라 할 수 있겠다.
아무튼 이런 파일들이 우리 눈에 보이기 전에는 어떻게 표현되는지 궁금하지 않은가?
그 중 대표격이 OBJ다. FBX, glTF, GLB 등도 있다.
.obj 파일은 텍스트 파일이다. 메모장이나 txt파일로 변환해 열면 앞에 붙은
알파벳을 보고 뒤의 수치가 무엇을 의미하는지 쉽게 알 수 있다. 1번부터 번호를 매길
텐데, OBJ의 특징이니 크게 불편해하지 않길 바란다. 주석은 #을 사용한다.
OBJ는 요즘에도 꽤 쓰인다. 그러나 용량도 크고 파싱 비용도 커서 실시간 렌더링에는
잘 안 쓰인다. 그럼 왜 배우는가. 우리에게는 성능이 최우선 아닌가? 앞서 말했듯 OBJ는
사람이 이해하기 쉽고, 구조가 단순하다. 오래된 만큼 여러 툴에서 지원한다.
v (vertex)
e.g. v 1.000000 0.000000 0.000000
정점을 의미하며 각각 x,y,z를 의미한다.
vt (vertex texture | vertex texture coordinate)
e.g. vt 1.000000 0.000000
uv 좌표다.
vn (vertex normal)
e.g. vn 0.000000 0.000000 1.000000
법선 벡터를 저장한 배열이며, face의 각 vertex corner가 인덱스로 참조한다.
하나의 위치 정점(v)에 대해 여러 개의 normal이 참조될 수 있다.
f (face)
면을 의미하며, 어떤 정점들을 연결해 geometry를 만들 것인지 명시한다.
e.g. f 1 2 3
이 경우는 1,2,3번 정점을 연결한 면이라는 의미다.
e.g. f 1/1 2/2 3/3
이건 1,2,3번이 각각 1,2,3번 UV에 대응된다는 의미다.
e.g. f 1/1/1 2/2/1 3/3/1
이건 위의 경우에 더해 normal까지 연결한다. 마지막의 경우
vertex corner의 위치는 v 3번, uv는 vt 3번, normal은 vn 1번이고
이 3개가 모여 face를 이룬다.
e.g. f 3//2 4//2 5//2
이건 UV가 없다.
o (object)
e.g. o Cube
이건 오브젝트의 이름이다. 파일 하나에 여러 오브젝트가 있을 수 있다.
g (group)
e.g. g Body
이건 그룹을 의미한다.
mtllib (material library)
e.g. mtllib house.mtl
이 OBJ가 사용한 머티리얼 파일을 의미한다.
usemtl (use material)
e.g. usemtl Brick \n f 1/1/1 2/2/1 3/3/1
이후 정의되는 face들에 적용될 머티리얼을 명시한다.
섹션과 비슷하다고 보면 이해하기 쉽겠다.
s (smoothing)
e.g. s 1 \n f 1/1/1 2/2/1 3/3/1
smoothing 처리를 명시하며 같이 묶이면 face는 normal을 공유해
마치 이어진 표면처럼 부드럽게 처리된다.
이걸 그대로 쓸 수는 없을 텐데
그렇다. 파싱이 필요하다.
아래는 언리얼 코드에서 사용하는 방식이다.
결국 obj는 파서가 필요하고 그 비용이 꽤 크다.
KeywordMap = {
"v" -> ParseVertex,
"vt" -> ParseUV,
"vn" -> ParseNormal,
...
공부자료
아래 예시 obj 파일을 보고 복기해보자.
mtllib warning\_01.mtl ← 이 OBJ가 사용하는 머티리얼 파일 경로
o Cylinder ← 오브젝트 이름 (파싱 안 함)
v 1.000000 0.000000 0.000000 ← 꼭짓점 위치 (Position)
v 0.951057 0.000000 0.309017 ← v 뒤에 X Y Z 좌표
v 0.809017 0.000000 0.587785
...
vt 0.025000 1.000000 ← 텍스처 좌표 (UV)
vt 0.025000 0.000000 ← vt 뒤에 U V (0\~1 범위)
vt 0.050000 1.000000
...
vn 0.975528 0.000000 0.154509 ← 법선 벡터 (Normal)
vn 0.880278 0.000000 0.448028 ← vn 뒤에 NX NY NZ
...
usemtl warning\_mat ← 여기서부터 이 머티리얼 사용 (Section 경계)
f 1/1/1 2/2/2 42/3/3 ← 면 정의: v인덱스/vt인덱스/vn인덱스
f 42/3/3 2/2/2 41/4/4 ← 삼각형 3개 꼭짓점
f 2/2/2 3/5/5 41/4/4
...
usemtl another\_mat ← 새 머티리얼 \= 새 Section 시작
f 81/161/81 82/162/82 ...
기억할 만한 OBJ 파일의 특징 : OBJ의 인덱싱
Position, UV, Normal이 각각 독립적인 인덱스를 가짐.
f 1/1/1 2/2/2 42/3/3
↑ ↑ ↑
│ │ └ Normal 인덱스 → Normals[0], Normals[1], Normals[2]
│ └── UV 인덱스 → UVs[0], UVs[1], UVs[2]
└──── Position 인덱스 → Positions[0], Positions[1], Positions[41]
GitHub 계정으로 댓글을 작성합니다.
현재 추천 수: 조회 중...
GitHub 이슈의 👍 반응을 집계합니다.
추천(👍) 남기기
이 문서 작업실에서 편집하기