obj文件格式学习(自用)

最近写图形学作业,需要读取obj文件并进行解析,所以学习了一下obj文件的格式,参考了一些博客,侵删。

Obj(或者.obj)是一种几何定义文件格式,文件格式是公开的,并能很好的在其他的3D应用中被支持。Obj文件格式是一种简单的单独表示3D几何图元的文件格式——也就是,顶点的坐标,每个顶点纹理的UV坐标,顶点法向量,以及组成多边形的面的顶点坐标、以及纹理UV坐标序列。面的顶点默认为逆时针顺序,法向量不是必须的。OBJ文件并非归一化的,但是可以在注释中加入缩放信息。
Obj文件可以是ASCII的编码(.obj)方式也可以是二进制格式(.mod)。以ASCII格式存储的obj文件必须用.obj作为文件拓展名。

1. 文件格式(File Format)

以哈希字符(#)开始的一行表示注释。

一个obj格式的文件可能包含了顶点数据,自由形式的曲面/表面属性,绘制索引序列,自由形式的曲面/表面内容声明,关联自由形式的表面,组和渲染属性信息。大多数常见的绘制索引表现为几何顶点,纹理坐标,顶点法线以及多边形的面:

1.1 几何顶点

一个顶点可以用字符v开头的一行来表示。接着后面跟上(x, y, z [w])的值来表示顶点坐标。W是可选项,默认为1.0。一些应用支持顶点颜色,通过在x y z后面跟上red, green, blue值来表示。颜色值的范围为0到1.0。

1.2 参数顶点空间

自由形式的几何图元声明可以使用字符vp开头的行来表示,用于定义一个曲面或者平面的参数空间中的顶点。"u"只能在曲面顶点中使用,u和v用于表示non-rational剪裁曲面的点,而u,v以及w表示rational剪裁曲面的点。

1.3 表面单元

表面通过一个包含顶点,纹理以及法线索引的序列来表示。类似四边形这种多边形可以通过多于三个包含顶点/纹理/法线索引来定义。
OBJ文件也支持自由形式的使用曲面和表现来定义对象的几何图元,例如NURBS表面。

顶点索引

一个合法的顶点索引符合上面定义的顶点序列格式。如果一个索引是正值则表示相对于顶点序列从1开始的偏移。如果一个索引是负的,表示从顶点序列结尾的偏移,从-1开始。
每个面都可以包含三个或者更多的顶点。

f v1 v2 v3 ....

纹理坐标索引

在描述一个平面的时候,纹理坐标索引作为可选项用于描述该顶点相关的纹理坐标。为了描述纹理坐标索引,必须在顶点坐标索引之后紧密添加一根斜线(/),之后再紧密添加纹理坐标索引。在斜线的前后都不能有空格。一个合法的纹理坐标索引从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文件不支持网格分级或者任何其他形式的动画或形变,例如顶点蒙皮或纹理变形。

材质引用

描述多边形的可见属性存储在外部的.mtl文件中。OBJ文件可能会引用超过一个的.mtl文件。.mtl文件可能包含一个或者多个不同命名的材质定义。

mtllib [external .mtl file name]
  ...

通过绘制单元之后的这个标签来指明使用的材质。材质名称必须和外部定义的.mtl文件名称匹配。

usemtl [material name]
  ...

objects名称和多边形group标签

o [object name]
  ...
  g [group name]
  ...
  • Group声明用于组织模型的单元(element)以及简化数据操作
  • Object声明用于标识在一个文件中的不同object单元
    所有的group声明都是基于状态的。依旧是一旦声明了group,将应用于所有之后的内容,直到下一个group 声明。
    通过Smoothing Group可以实现多边形平滑渲染。

单个obj文件中可以包含多个object标签或group标签。
其中,o标签和g标签仅仅是在组织上进行分组而存在的,例如一个o标签下,可能包含多个g,或者一个g开头的顶点数据集合之后包含多个g组织描述的三角面。也有将usemtl标签作为网格分组的,原因是考虑了同一组网格使用了相同的纹理。但有个不方面的地方就是对于需要单个控制的地方,略显不便。例如一个o或者g标签的数据集合表示人脸,之后眼睛,耳朵,鼻子等五官分作不同的g来组织,使用同一个纹理。采用usemtl分组的话,如果想对眼睛,嘴巴,等进行单独变换的时候很不方便。因此,本人还是采用g来进行网格划分。
通常处理obj文件的时候,会抛弃顶点法线数据,而通过顶点信息来进行计算。有了以上的顶点坐标、法线、纹理坐标等信息,就可以进行3D模型文件的渲染了。


 


参考来源:https://www.jianshu.com/p/f7f3e7b6ebf5

 

发布了55 篇原创文章 · 获赞 63 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/m0_38068229/article/details/103424196