前言
这篇文章是我在着手准备实现物理渲染的时候在为项目搭框架的时候想到要写的。在之前的学习中,虽然也是接触了模型以及模型导入库 Assimp
但是却没有太多的概念。虽然知道网格,也知道网格的实现以及原理,但是并未多次用过,所以在这里准备好好复习一遍。
Mesh
首先甩上一个概念:Mesh(网格) 。在维基百科中被这样定义:
多边形网格(Polygon mesh)是三维计算机图形学中表示多面体形状的顶点与多边形的集合,它也叫作非结构网格。
这些网格通常由三角形、四边形或者其它的简单凸多边形组成,这样可以简化渲染过程。但是,网格也可以包括带有空洞的普通多边形组成的物体。
我们这篇文章中要介绍的就是 Mesh 以及 Model 。
我们在不管是 OpenGL 还是 Direct3D 的学习教程中,都是使用基本图元(primitive)来进行绘制,或者是一个三角形,一个矩形或者一个三维的立方体。这些东西都比较简单,我们可以很简单的描述他。比如我们使用两个三角形组成一个平面矩形,使用十二个三角形组成一个三维立方体,两个三角形组成一个面。我们很容易想象得到这个立方体。
但是如果非常复杂,比如一个人,一辆坦克。如果我们说他由几千个三角形组成,有几十个几百个面等等。能想象得到吗?
在这里我们会将使用一个封装的数据类型来描述比较复杂的物体,就是 Mesh
。我们一般由一个 Mesh 来代表一个网格,这个 Mesh
会封装相当多的数据,比如顶点、边、面,而且包含了顶点坐标,纹理坐标,法向量,材质属性等属性。下面是维基百科上的一个例子:
Mesh可以包含多个Face,一个Face是Mesh中一个可绘制的基本图元,例如三角形,多边形,点。要想模型更加逼真,一般需要增加更多图元使Mesh更加精细,当然这也会受到硬件处理能力的限制,例如PC游戏的处理能力要强于移动设备。由于多边形都可以划分为三角形,而三角形是图形处理器中都支持的基本图元,因此使用得较多的就是三角形网格来建模。
其实我们在学习模型那一节的时候,实现过一个 Mesh 的类,也调用了 Assimp 库来导入模型,可以看这里:【OpenGL】13-Mesh与Model类 。
Model
接下来我们来看看模型(OBJ文件) 。
OBJ (or .OBJ) is a geometry definition file format first developed by Wavefront Technologies for its Advanced Visualizer animation package. The file format is open and has been adopted by other 3D graphics application vendors.
The OBJ file format is a simple data-format that represents 3D geometry alone — namely, the position of each vertex), the UV position of each texture coordinate vertex, vertex normals, and the faces that make each polygon defined as a list of vertices, and texture vertices. Vertices are stored in a counter-clockwise order by default, making explicit declaration of face normals unnecessary. OBJ coordinates have no units, but OBJ files can contain scale information in a human readable comment line.
简单来说,OBJ 文件就是定义模型的文件。在 OpenGL 中我们使用 Assimp 库来导入 OBJ 文件,OBJ 文件则可以通过各种 3D 建模工具进行导出。OBJ 本质上是一个文本文件:
OBJ文件特点
(1)OBJ是一种3D模型文件,因此不包含动画、材质特性、贴图路径、动力学、粒子等信息。
(2)OBJ文件主要支持多边形(Polygons)模型。
虽然OBJ文件也支持曲线(Curves)、表面(Surfaces)、点组材质(Point Group Materials),但Maya导出的OBJ文件并不包括这些信息。
(3)OBJ文件支持三个点以上的面,这一点很有用。
(4)OBJ文件支持法线和贴图坐标。 在其它软件中调整好贴图后,贴图坐标信息可以存入OBJ文件中,这样文件导入Maya后只需指定一下贴图文件路径就行了,不需要再调整贴图坐标了。
(5)OBJ文件不支持有孔的多边形面。
(6)OBJ文件不包含面的颜色定义信息,不过可以引用材质库,材质库信息储存在一个后缀是”.mtl”的独立文件中。关键字”mtllib”即材质库的意思。
OBJ文件的前缀
OBJ文件以纯文本的形式存储了模型的顶点、法线和纹理坐标和材质使用信息。
在OBJ文件中,每行的格式如下:前缀 参数1 参数2 参数3 …
(前缀标识了这一行所存储的信息类型。参数则是具体的数据。)
OBJ文件的前缀可以有:
v 表示本行指定一个顶点。此前缀后跟着3个单精度浮点数,分别表示该定点的X、Y、Z坐标值
vt 表示本行指定一个纹理坐标。此前缀后跟着两个单精度浮点数。分别表示此纹理坐标的U、V值
vn 表示本行指定一个法线向量。此前缀后跟着3个单精度浮点数,分别表示该法向量的X、Y、Z坐标值
f 表示本行指定一个表面(Face)。一个表面实际上就是一个三角形图元。此前缀行的参数格式后面将详细介绍。
usemtl 此前缀后只跟着一个参数。该参数指定了从此行之后到下一个以usemtl开头的行之间的所有表面所使用的材质名称。该材质可以在此OBJ文件所附属的MTL文件中找到具体信息。
mtllib 此前缀后只跟着一个参数。该参数指定了此OBJ文件所使用的材质库文件(*.mtl)的文件路径
以“#”开头的表示注释的前缀,以g开头的表示组的前缀。这些前缀并不影响模型的外观,可以忽略它们。