2-模型数据
条评论 这是3D可视化教程系列的文章,如果第一次阅读请先阅读《3D可视化教程导读》。
这篇文章可以 快速略过 ,当你觉得“需要研究一下”时再深入了解。
源码及3D项目文件
源码及工程项目都放到github上。
源码:threejs-example
OBJ格式
现在我们先研究一下最简单的3D文件数据是长什么样的,长宽高各为1米的立方体并导出OBJ格式:
导出能看到一个.obj文件与.mtl文件。 根据OBJ文件格式的官方文档定义,.obj文件保存的是3D模型的几何结构数据与其它属性数据(每个顶点的位置、UV位置、法线,以及组成面(多边形)的顶点列表等数据),.mtl文件(Material library files官方文档)保存的是材质数据(颜色、纹理、贴图、反光等等用于描述物体外表的参数,3D模型创建时会使用默认材质。)。在windows10下直接点击.obj文件,会使用3D Viewer查看3D模型:
用vscode打开这些文件,就能看到文件里的内容。这里我添加了注释,一起看看.obj里的内容:
1 | # Blender v2.82 (sub 7) OBJ File: '' |
GLTF/GLB格式
同理,导出GLTF格式(gltf官方文档,GLB是二进制格式形式,更节省空间。),gltf格式是可以将二进制的图片内嵌到一个文件里,不像OBJ格式会拆分成很多个文件。但由于顶点数据以二进制的方式存到buffers,并不方便分析,不多讲,自己看着图来分析就行了。
1 | { |
说明
索引
模型数据的特点是使用 索引 ,这样做的好处是可以共用数据。比如说,有10个立方体,他们某个顶点都是位于(1,2,3),那么他们的顶点都指向这个顶点,而不需要给每个立方体都保存一份(1,2,3)的数据,原本需要十个顶点数据,现在只需要保存一个顶点数据,节约了存储空间。特别是材质,很多情况下相同的物体都是使用相同的材质,假设10个立方体都使用了红色的材质A,当把材质A的颜色改为绿色时,那么这10个立方体都会变成绿色。
如果想给这10个立方体都要显示不同的颜色,那就得需要10个不同颜色的材质。在编程时就需要注意,你修改的这个物体材质时,会不会其它物体也在使用,会不会影响到其它物体?如果不想影响到其它物体,就需要将当前材质克隆一份出来,赋予该物体新的材质,再去修改。
顶点坐标
顶点相连组成线,线线相连组成面,面面相连组成物体,所以可以看到几何图形数据主要是顶点坐标(vertex)。
UV贴图
当需要将一张图片贴到一个物体上时,就需要UV贴图。UV贴图的本质就是,设置点坐标与图片的横纵坐标一一对应。
three.js数据结构
一个拥有几何结构(geometry)与材质(material)的3D物体被称为Mesh(被翻译成网格),three.js从3D文件里读取数据会换成其对应的数据,常用属性如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35Mesh (extends Object3D) 继承Object3D对象
- geometry:Geometry/BufferGeometry 记录点线面的数据
- material:Material 记录材质数据
Geometry 几何图形
- vertices:Array 存放几何数据
BufferGeometry 更高效的Geometry
- attributes:BufferAttribute 存放几何数据
Material 材质
- opacity:Float 透明度(0.0-1.0 ,transparent为true时才会表现出透明效果)
- side:Integer 渲染面(前/后/双面 渲染:THREE.FrontSide,THREE.BackSide,THREE.DoubleSide)
- color:Color 颜色
- emissive:Color 发光色
- transparent:Boolean 是否透明
Object3D 3D对象
- children:Object3D[] 子对象
- matrix:Matrix4 相对坐标矩阵(相对于父级)
- matrixWorld:Matrix4 世界坐标矩阵
- name:String 名称
- parent:Object3D 上级对象
- position:Vector3 位置坐标(x,y,z)
- renderOrder:Integer 渲染顺序
- rotation:Euler 角度
- scale:Vector3 缩放倍数
- userData:Object 放自定义数据的地方
- uuid:String 唯一ID
- visible:Boolean 是否可见
Vector3 3维向量
- x:Float x值
- y:Float y值
- z:Float z值
我经常在console里打印数据出来分析:
有很多东西在前期会搞不懂,直到读完《交互式计算机图形学——基于WebGL的自顶向下方法(第七版)》搞懂很多原理之后,就好多了。前期主要是参考模仿代码做几个效果,直到有一种强烈的欲望想去了解原理时,再去了解原理。
其它
- obj文件格式比较简单,很多如不动点(pivot)、分层等数据是不能保存下来的。
- gltf 与 glb格式可以使用工具相互转换。(有对应的vscode插件可以实现)
- 网上有很多工具可以将不同格式的文件转换成gltf/glb格式,但并不保证能完全兼容,转换出来的效果不一定能完全符合预算。
- blender并不能把所有的数据导出来。(你可以试一下,使用blender导出的3D文件,再重新导入,会发现有可能不一样,那是因为blender没有导出对应的数据(比如alphaMap贴图)或该3D文件格式不支持那些数据。)