3D模型OBJ格式详解

在这里插入图片描述

竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生~
个人主页: rainInSunny  |  个人专栏: C++那些事儿Learn OpenGL In Qt

写在前面

  OBJ格式是一种简单的文本格式,用于描述三维模型的几何形状和材质信息,因为其文本格式的属性,学习OBJ格式能够很好理解在3D图形中是如何描述一个3D对象的。OBJ通常由顶点、法线、纹理坐标和面片组成,可以包含多个对象和材质。OBJ格式通常用于编辑器和渲染器之间的数据交换,以便在不同的软件中共享和处理三维模型数据。由于其简单易读的特性,OBJ格式在计算机图形学领域中被广泛应用,目前几乎所有知名的3D软件都支持OBJ文件的读写。
  如果大家需要可用的OBJ格式3D模型,点这里

OBJ格式解析

  OBJ文件是一种文本文件,可以直接用写字板打开进行查看和编辑修改。OBJ文件不需要任何种文件头(File Header),尽管经常使用几行文件信息的注释作为文件的开头。OBJ文件由一行行文本组成,注释行以符号“#”为开头,空格和空行可以随意加到文件中以增加文件的可读性。有字的行都由一两个标记字母也就是关键字(Keyword)开头,关键字可以说明这一行是什么样的数据。多行可以逻辑地连接在一起表示一行,方法是在每一行最后添加一个连接符(/)。注意连接符(/)后面不能出现空格或Tab格,否则将导致文件出错。理解OBJ文件内容需要知道各个关键字含义。

  • 顶点数据(Vertex data)

    • v 几何体顶点(Geometric vertices)
    • vt 贴图坐标点(Texture vertices)
    • vn 顶点法线(Vertex normals)
    • vp 参数空格顶点 (Parameter space vertices)
  • 自由形态曲线(Free-form curve)/表面属性(surface attributes)

    • deg 度(Degree)
    • bmat 基础矩阵(Basis matrix)
    • step 步尺寸(Step size)
    • cstype 曲线或表面类型 (Curve or surface type)
  • 元素(Elements)

    • p 点(Point)
    • l 线(Line)
    • f 面(Face)
    • curv 曲线(Curve)
    • curv2 2D曲线(2D curve)
    • surf 表面(Surface)
  • 自由形态曲线(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)
  • 成组(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)

OBJ文件示例

# Blender v2.64 (sub 0) OBJ File: 'nanosuit.blend'
# www.blender.org
mtllib nanosuit.mtl
o Visor
v 0.320384 14.057541 0.507779
v 0.385196 13.984534 0.445066
v 0.416643 14.114325 0.462461
......
......
v -0.216001 14.187331 0.577817
v -0.397356 14.114325 0.462461
v -0.365670 13.984534 0.445066
vt 0.439941 0.453613
vt 0.541992 0.372070
vt 0.564941 0.521973
......
......
vt 0.046417 0.900818
vt 0.447510 0.627197
vt 0.446777 0.559082
vn 0.496902 -0.240822 0.833674
vn 0.524613 -0.236702 0.817743
vn 0.581713 -0.161901 0.797082
......
......
vn -0.421766 -0.127873 0.897610
vn -0.571764 -0.123020 0.811121
vn -0.523911 -0.237526 0.817957
usemtl Glass
s 1
f 1/1/1 2/2/2 3/3/3
f 4/4/4 5/5/5 6/6/6
f 6/6/6 7/7/7 4/4/4
......
......
f 37/14/37 51/3/51 47/28/47
f 48/1/48 47/28/47 51/3/51
f 51/3/51 52/2/52 48/1/48

  上面给出了一个obj对象内容节选,可以看到用到的关键字并不多,一般情况只需要掌握这些基本关键字。

  • #后面的内容表示注释。
  • mtllib关键字后参数为文件名称,指定了obj文件所使用的材质库文件(mtl文件)的文件名称。
  • o关键字表示开始一个对象,一个对象包含顶点、纹理坐标、法向量、材质等信息。
  • v关键字表示对象中的顶点坐标信息,依次为x、y、z分量。
  • vt关键字表示纹理坐标,依次为x、y两个分量。值大小一般在0~1之间。
  • vn关键字表示法向量信息,依次为x、y、z分量。
  • usemtl关键字后参数为材质名称,指定了从此行之后到下一个以usemtl开头的行之间的所有表面所使用的材质名称,该材质可以在此obj文件所附属的mtl文件中找到具体信息。
  • 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等是对应顶点的法线方向序号。

MTL文件

  obj文件不包含面的颜色定义信息,不过可以引用材质库,材质库信息储存在一个后缀是".mtl"的独立文件中。mtl文件是obj文件附属的材质库文件,材质库中包含材质的漫射(diffuse),环境(ambient),光泽(specular)的RGB的定义值,以及反射(specularity),折射(refraction),透明度(transparency)等其它特征。
mtl文件关键字:

  • newmtl: 定义新的材质组,后面参数为材质组名称
  • Ka: 材质的环境光颜色(ambient color)
  • Kd: 材质的散射光颜色(diffuse color)
  • Ks: 材质的镜面光颜色(specular color)
  • Ke: 材质的放射光颜色(emissive color)
  • Ns: 材质的光亮度
  • d,Tr 均可用于定义材质的Alpha透明度
  • sharpness:材质的锐度(sharpness)
  • illum: 照明度(illumination)后面可接0~10范围内的数字参数
    • 0 Color on and Ambient off
    • 1 Color on and Ambient on
    • 2 Highlight on
    • 3 Reflection on and Ray trace on
    • 4 Transparency: Glass on
      Reflection: Ray trace on
    • 5 Reflection: Fresnel on and Ray trace on
    • 6 Transparency: Refraction on
      Reflection: Fresnel off and Ray trace on
    • 7 Transparency: Refraction on
      Reflection: Fresnel on and Ray trace on
    • 8 Reflection on and Ray trace off
    • 9 Transparency: Glass on ,Reflection: Ray trace off
    • 10 Casts shadows onto invisible surfaces
  • Ni : 材质的光密度(optical density)
  • Tf: 材质的透射滤波(transmission filter),对应数据为r,g,b值
  • map_Ka、map_Kd、map_Ks、map_Bump表示材质的环境,散射、镜面和凹凸贴图,对应数据为贴图文件名称
  • refl: 材质的反射属性

  下面节选了部分mtl文件。当描述一个模型时,如果材质颜色单一,可以直接使用Ka、Kd和Ks来描述材质的环境光颜色、散射光颜色和镜面光颜色。当材质颜色丰富的时候,如果要描述则需要大量的数据,这种情况更适合通过map_Ka、map_Kd和map_Ks来描述材质的环境光颜色、散射光颜色和镜面光颜色。这样渲染过程中结合模型的纹理坐标vt就能通过颜色采样获取各个点的材质颜色。

# Blender MTL File: 'nanosuit.blend'
# Material Count: 6
newmtl Arm
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ni 1.000000
d 1.000000
illum 2
map_Kd arm_dif.png
map_Bump arm_showroom_ddn.png
map_Ks arm_showroom_spec.png
......
......

OBJ渲染简述

  以OpenGL渲染为例,首先需要的是模型的顶点信息v,顶点信息决定了几何形状。其次渲染过程还需要得到模型的颜色信息。为了模拟现实场景中的光照,采用冯氏光照模型计算颜色信息。obj格式提供关于颜色计算的相关参数也是和冯氏光照基本对应的。冯氏光照中将光照分为环境光、散射光(漫反射光)和镜面反射光。obj对应的mtl文件中提供了map_Kamap_Kdmap_Ks贴图,结合obj文件中的纹理坐标vt对这些贴图进行采样,获取采样值后结合法向量vn和光源信息用冯氏光照模型计算就能得到每个顶点环境光、散射光颜色和镜面反射光颜色。由于结合了光源信息,这样计算出来的颜色会随着光源变化而变化,模拟了现实场景。
  注意并不是所有mtl文件中都包含map_Ka、map_Kd和map_Ks贴图,有的可能只有一个或者两个贴图。另外贴图是以路径的形式给出,如果路径没有前缀信息,需要在加载模型时将贴图、obj和mtl文件放在同级目录。如果mtl文件中没有光照贴图,那就只能通过KaKdKs作为环境光、散射光和镜面反射光,一般用于模型颜色单一的场景。

欢迎留言讨论,创作不易,感谢点赞、关注和收藏

  • 13
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值