加載3D模型的時候,遇到.obj格式的模型文件。之前有專門看過相關(guān)的資料,可惜沒有總結(jié),一下就忘了。再次用到,又去搜索了一番,發(fā)現(xiàn)網(wǎng)上很多文章講的不是很全面。于是就找到百科上的文檔,總結(jié)一下。
Obj(或者.obj)是一種幾何定義文件格式,第一次是 Wavefront Technologies在他們的可視化加強動畫包里面使用的。文件格式是公開的,并能很好的在其他的3D應用中被支持。
Obj文件格式是一種簡單的單獨表示3D幾何圖元的文件格式——也就是,頂點的坐標,每個頂點紋理的UV坐標,頂點法向量,以及組成多邊形的面的頂點坐標、以及紋理UV坐標序列。面的頂點默認為逆時針順序,法向量不是必須的。OBJ文件并非歸一化的,但是可以在注釋中加入縮放信息。
Obj文件可以是ASCII的編碼(.obj)方式也可以是二進制格式(.mod)。以ASCII格式存儲的obj文件必須用.obj作為文件拓展名。
1. 文件格式(File Format)
以哈希字符(#)開始的一行表示注釋。
# this is a comment
一個obj格式的文件可能包含了頂點數(shù)據(jù),自由形式的曲面/表面屬性,繪制索引序列,自由形式的曲面/表面內(nèi)容聲明,關(guān)聯(lián)自由形式的表面,組和渲染屬性信息。大多數(shù)常見的繪制索引表現(xiàn)為幾何頂點,紋理坐標,頂點法線以及多邊形的面:
# List of geometric vertices, with (x,y,z[,w]) coordinates, w is optional and defaults to 1.0.
v 0.123 0.234 0.345 1.0
v ...
...
# List of texture coordinates, in (u, v [,w]) coordinates, these will vary between 0 and 1, w is optional and defaults to 0.
vt 0.500 1 [0]
vt ...
...
# List of vertex normals in (x,y,z) form; normals might not be unit vectors.
vn 0.707 0.000 0.707
vn ...
...
# Parameter space vertices in ( u [,v] [,w] ) form; free form geometry statement ( see below )
vp 0.310000 3.210000 2.100000
vp ...
...
# Polygonal face element (see below)
f 1 2 3
f 3/1 4/2 5/3
f 6/4/1 3/5/3 7/6/5
f 7//1 8//2 9//3
f ...
...
1.1 幾何頂點
一個頂點可以用字符v開頭的一行來表示。接著后面跟上(x, y, z [w])的值來表示頂點坐標。W是可選項,默認為1.0。一些應用支持頂點顏色,通過在x y z后面跟上red, green, blue值來表示。顏色值的范圍為0到1.0。
1.2 參數(shù)頂點空間
自由形式的幾何圖元聲明可以使用字符vp開頭的行來表示,用于定義一個曲面或者平面的參數(shù)空間中的頂點。"u"只能在曲面頂點中使用,u和v用于表示non-rational剪裁曲面的點,而u,v以及w表示rational剪裁曲面的點。
1.3 表面單元
表面通過一個包含頂點,紋理以及法線索引的序列來表示。類似四邊形這種多邊形可以通過多于三個包含頂點/紋理/法線索引來定義。
OBJ文件也支持自由形式的使用曲面和表現(xiàn)來定義對象的幾何圖元,例如NURBS表面。
頂點索引
一個合法的頂點索引符合上面定義的頂點序列格式。如果一個索引是正值則表示相對于頂點序列從1開始的偏移。如果一個索引是負的,表示從頂點序列結(jié)尾的偏移,從-1開始。
每個面都可以包含三個或者更多的頂點。
f v1 v2 v3 ....
紋理坐標索引
在描述一個平面的時候,紋理坐標索引作為可選項用于描述該頂點相關(guān)的紋理坐標。為了描述紋理坐標索引,必須在頂點坐標索引之后緊密添加一根斜線(/),之后再緊密添加紋理坐標索引。在斜線的前后都不能有空格。一個合法的紋理坐標索引從1開始,并符合之前描述的格式。每個面可以包含三個或者更多的單元。
f v1/vt1 v2/vt2 v3/vt3 ...
頂點法線索引
法線索引用于描述頂點的法向量,在描述面的時候是可選項。要添加頂點法線索引,必須在紋理索引之后添加第二根斜線(/),然后在之后添加法線索引。斜線前后不能有空格。合法的法線索引從1開始,并符合之前面描述的格式。每個面可以包含三個或者更多的單元。
f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...
頂點坐標法線索引(不包含紋理索引)
可以在定義幾何圖元的時候忽略紋理坐標索引,但是必須在頂點坐標索引后加上兩根斜線(//),然后添加法線索引。
f v1//vn1 v2//vn2 v3//vn3 ...
其他幾何格式
Obj文件采用若干差值方法來支持高階表面,例如泰勒和B差值,盡管支持這些特性要使用一些非標準的第三方文件。Obj文件不支持網(wǎng)格分級或者任何其他形式的動畫或形變,例如頂點蒙皮或紋理變形。
材質(zhì)引用
描述多邊形的可見屬性存儲在外部的.mtl文件中。OBJ文件可能會引用超過一個的.mtl文件。.mtl文件可能包含一個或者多個不同命名的材質(zhì)定義。
mtllib [external .mtl file name]
...
通過繪制單元之后的這個標簽來指明使用的材質(zhì)。材質(zhì)名稱必須和外部定義的.mtl文件名稱匹配。
usemtl [material name]
...
objects名稱和多邊形group標簽
o [object name]
...
g [group name]
...
- Group聲明用于組織模型的單元(element)以及簡化數(shù)據(jù)操作
- Object聲明用于標識在一個文件中的不同object單元
所有的group聲明都是基于狀態(tài)的。依舊是一旦聲明了group,將應用于所有之后的內(nèi)容,直到下一個group 聲明。
通過Smoothing Group可以實現(xiàn)多邊形平滑渲染。
s 1
...
# Smooth shading can be disabled as well.
s off
...
單個obj文件中可以包含多個object標簽或group標簽。
其中,o標簽和g標簽僅僅是在組織上進行分組而存在的,例如一個o標簽下,可能包含多個g,或者一個g開頭的頂點數(shù)據(jù)集合之后包含多個g組織描述的三角面。也有將usemtl標簽作為網(wǎng)格分組的,原因是考慮了同一組網(wǎng)格使用了相同的紋理。但有個不方面的地方就是對于需要單個控制的地方,略顯不便。例如一個o或者g標簽的數(shù)據(jù)集合表示人臉,之后眼睛,耳朵,鼻子等五官分作不同的g來組織,使用同一個紋理。采用usemtl分組的話,如果想對眼睛,嘴巴,等進行單獨變換的時候很不方便。因此,本人還是采用g來進行網(wǎng)格劃分。
通常處理obj文件的時候,會拋棄頂點法線數(shù)據(jù),而通過頂點信息來進行計算。有了以上的頂點坐標、法線、紋理坐標等信息,就可以進行3D模型文件的渲染了。
下面是一個簡單3D模型的光照效果。猛戳代碼
