本文最后更新于:2024年7月12日 上午
OBJ是一种 3D 文件格式, 本文记录相关内容。
OBJ 格式
OBJ 是一种几何定义文件格式,Wavefront Technologies 公司在可视化加强动画包中第一次使用了这个格式,文件格式是公开的,并具有及其优质的兼容性和跨平台、跨行业的通用性,在所有 3D 应用软件中被支持。
OBJ 文件可以以 ASCII 编码也可以以二进制格式编码,以 ASCII 格式编码的后缀名为 .obj,以二进制格式编码的后缀名为 .mod。OBJ 格式的三维网格模型储存了模型的顶点、面片、法向量纹理等几何信息。
OBJ 文件使用标准的 Polygon(多边形) 储存格式,直接储存顶点坐标和法线等数据,这导致 OBJ 文件无法导出骨骼动画,只能储存静态模型和材质信息。
规范
OBJ文件不需要任何种文件头,文件由一行行文本组成,注释行以符号“#”为开头,空格和空行可以随意加到文件中。
有字的行都由一两个标记字母也就是关键字(Keyword)开头,关键字可以说明这一行是什么样的数据。
多行可以逻辑地连接在一起表示一行,方法是在每一行最后添加一个连接符()。 注意连接符()后面不能出现空格或Tab格,否则将导致文件出错。
OBJ
文件一般会与 mtl
文件与 贴图图像
文件共用, 组成一个 3D 模型文件, 有时还会附带一个 xml
文件记录坐标偏移量。
obj 文件格式
其中常见的obj数据的组成形式为:
- 首行:
mtllib *.mtl
表示使用哪个mtl文件,以mtllib开头 - 顶点坐标:
v x y z
表示一个顶点的坐标,以v开头 - 纹理坐标:
vt u v
表示一个纹理的坐标,以vt开头 - 引用的材质:
usemtl *
表示引用mtl文件的哪部分纹理,以usemtl开头 - 面索引:
f v_i1/u_i1 v_i2/u_i2 v_i3/u_i3
,以f开头,分别记录 顶点的序号和纹理的序号,序号从1开始,一个面由三个顶点组成,所以有三个顶点序号和纹理序号
mtl 文件格式
mtl记录了纹理的一些配置信息,主要有:
newmtl *
: 创建一个材质,材质名为*,对应obj中的usemtl *
ka * * *
: 环境颜色kd * * *
:漫反射颜色d *
: 透明度Ns: *
: 高光指数illum: *
: 光照模型map_kd: *.jpg
:纹理图片的名称
xml 文件格式
有时会存在 xml 文件metadata.xml
,记录坐标系以及起始坐标偏移量,例如:
1 |
|
这样实际的坐标系为 4538,真实坐标为 obj 记录坐标加上 SRSOrigin
标签内坐标。
OBJ 模型示例
obj 模型内部以文本存储, 示例模型如下:
1 |
|
特点说明:
- 注释行以符号 “#” 为开头,空格和空行可以随意加到文件中。
- 有字的行都由一两个标记字母也就是关键字(Keyword)开头,关键字可以说明这一行是什么样的数据。
- 多行可以逻辑地连接在一起表示一行,方法是在每一行最后添加一个连接符 ()。 注意连接符 () 后面不能出现空格或 Tab 格,否则将导致文件出错。
o
用于引入一个新的 object。
关键字
顶点数据(Vertex data):
- v 顶点(Vertices)
- vt 纹理坐标(Texture vertices)
- vn 顶点法向量(Vertex normals)
- vp 参数空格顶点 (Parameter space vertices)
元素(Elements):
- p 点(Point)
- l 线(Line)
- f 面(Face)
- curv 曲线(Curve)
- curv2 2D曲线(2D curve)
- surf 表面(Surface)
成组(Grouping):
- g 组名称(Group name)
- s 光滑组(Smoothing group)
- mg 合并组(Merging group)
- o 对象名称(Object name)
显示(Display)/渲染属性(render attributes):
- bevel 导角插值(Bevel interpolation)
- c_interp 颜色插值(Color interpolation)
- d_interp 溶解插值(Dissolve interpolation)
- lod 细节层次(Level of detail)
- usemtl 材质名称(Material name)
- mtllib 材质库(Material library)
- shadow_obj 投射阴影(Shadow casting)
- trace_obj 光线跟踪(Ray tracing)
- ctech 曲线近似技术(Curve approximation technique)
- stech 表面近似技术 (Surface approximation technique)
自由形态曲线(Free-form curve)/表面属性(surface attributes):
- deg 度(Degree)
- bmat 基础矩阵(Basis matrix)
- step 步尺寸(Step size)
- cstype 曲线或表面类型 (Curve or surface type)
自由形态曲线(Free-form curve)/表面主体陈述(surface body statements):
- parm 参数值(Parameter values )
- trim 外部修剪循环(Outer trimming loop)
- hole 内部整修循环(Inner trimming loop)
- scrv 特殊曲线(Special curve)
- sp 特殊的点(Special point)
- end 结束陈述(End statement)
自由形态表面之间的连接(Connectivity between free-form surfaces):
- con 连接 (Connect)
重点关键字详解
obj 格式主要有一下 4 种关键字:
1. v 顶点
1 |
|
v
表示顶点位置,值分别为 x、y、z,即每个顶点在 X、Y、Z 轴的坐标。
- 格式:v x y z
- 意义:每个顶点的坐标
2. vt 顶点纹理坐标
1 |
|
- 格式:vt u v w
- 意义:绘制模型的三角面片时,每个顶点取像素点时对应的纹理图片上的坐标。纹理图片的坐标指的是,纹理图片如果被放在屏幕上显示时,以屏幕左下角为原点的坐标。
- 注意:w 一般用于形容三维纹理,大部分是用不到的,基本都为 0
3. vn 顶点法向量
1 |
|
- 格式:vn x y z
- 意义:绘制模型三角面片时,需要确定三角面片的朝向,整个面的朝向,是由构成每个面的顶点对应的顶点法向量的做矢量和决定的(xyz 的坐标分别相加再除以 3 得到的)。
4. f 面
1 |
|
- 格式 :f v/vt/vn v/vt/vn v/vt/vn(f 顶点索引 / 纹理坐标索引 / 顶点法向量索引)
- 意义:绘制三角面片的依据,每个三角面片由三个f构成,由f可以确定顶点、顶点的对应的纹理坐标(提取纹理图片对应该坐标的像素点)、通过三个顶点对应的顶点法向量可以确定三角面的方向。
- 补充:以 f 开头的行表示面片,之后跟上索引语句来将顶点分配给面片,索引语句一共有四种格式:
- 顶点索引:以
f v1 v2 v3 …
的格式分配的面片。v1、v2、v3 等是顶点序号,以文件中第一个 v 标志行为 1,逐个递增。一个面片至少分配 3 个顶点,但可以分配超过 3 个顶点,即 obj 格式不保证三角面。面中顶点的声明顺序一般按逆时针方向,即遵循右手螺旋定则。 - 纹理坐标索引:以
f v1/vt1 v2/vt2 v3/vt3 …
的格式分配的面片。v1、v2、v3 等是顶点序号,vt1、vt2、vt3 等是对应顶点的纹理坐标序号,序号分配方式和 v 类似。 - 顶点法线索引:以
f v1//vn1 v2//vn2 v3//vn3 …
的格式分配的面片。v1、v2、v3 等是顶点序号,vn1、vn2、vn3 等是对应顶点的法线方向序号,序号分配方式和 v 类似。 - 顶点纹理法线索引:以
f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 …
的格式分配的面片。v1、v2、v3 等是顶点序号,vt1、vt2、vt3等是对应顶点的纹理坐标序号,vn1、vn2、vn3 等是对应顶点的法线方向序号。
- 顶点索引:以
补充说明
模型一般通过 3d 建模软件,例如 Blender, 3DS Max 或者 Maya 等工具建模,导出时的数据格式变化较大,我们导入模型到 OpenGL 的任务就是:将一种模型数据文件表示的模型,转换为 OpenGL 可以利用的数据。例如上面的 Obj 文件中,我们需要解析顶点位置,纹理坐标等数据,构成 OpenGL 可以渲染的 Mesh 对象。
obj 文件在导出时一般包括两个文件 .obj 文件和 .mtl 文件和贴图图像。其中 obj 文件表示模型网络文件,mtl 文件表示模型使用的材质。
一般 obj 文件:
- 顶点的个数与顶点法向量的个数一样多。
- 顶点的个数不一定与纹理坐标的个数一样多,因为有可能很多顶点公用一个纹理坐标的像素。
- 面索引的个数也与其余数据数量无关。
- 最终每个三角面的颜色,是由构成这个三角面的三个顶点进行插值计算(有例如:一个三角面其中两个顶点对应的纹理坐标是黑色的,另外一个是白色,那整个面呈现的颜色是由黑变白渐变,而不是三个颜色值的平均值。这就是插值的作用)来确定。所以面的颜色有可能不与每个点的颜色一致。
Python 解析obj数据
方法一
通过pywavefront
库解析obj模型
1 |
|
model 成员:
-
materials
: 记录了材质信息 -
vertices
: 一个坐标数组,五个数据一组,前两位表示纹理坐标,后三位表示顶点坐标 -
mtllibs
: 模型使用的mtl文件名,以数组形式存储 -
vertices
: 顶点坐标数组 -
meshes
: 格网列表,表示面数据索引集合
方法二
直接读取其中的数据,例如获取所有节点的程序:
1 |
|
参考资料
- https://www.cnblogs.com/linuxAndMcu/p/14483146.html
- https://www.cnblogs.com/liangtao999/p/13398348.html
- https://www.cnblogs.com/liangtao999/p/13398348.html
文章链接:
https://www.zywvvd.com/notes/3d/data-format/obj-intr/obj-intr/
“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”
微信支付
支付宝支付