这篇文章是给第一次接触three.js或者看过教程但对three.js各种类型的封装类分不清的朋友去形象化理解three.js下的3D开发过程。
谁会不想拥有在web端进行3d开发的技能呢,但3d开发是基于图形学理论基础的,而且这个理论基础的门槛并不低。当然好在现在有基于webgl基础上进行封装的three.js框架,不再需要往底层进行学GLSL语言等基础知识了。当然,想精通还是得往底层去学。而three.js更偏向是业务层面的应用技术,本文会对three.js进行一个比较形象化的简述,希望能帮助到和我一样没啥天赋,但又想往这个方向学习的朋友,可以快速了解到3D开发是怎样的一个逻辑。本文只是描述3D开发的逻辑,不会有代码的展示,因此基本都是文字内容。
现在浏览器基本上都支持webgl了,当然ie不算浏览器。好,回过话题,three.js的3d开发虽然是基于webgl封装的,three.js却可以无需去专门学wegbl,因为three.js是应用层面,就好比你学习使用电脑,并不需要知道电脑是怎么样做出来的一样。那么怎么去使用three.js做web端3D开发呢?首先定一个目标,3d开发那就创建一个3D的球,下面一步步形象化描述这一过程。
1)环境
打开threejs教程,会有教你怎么一步步去创建场景,相机,物体,还有渲染,但一下子接收一堆封装类,会觉得很懵逼,尽管能临摹教程做出东西,但好像会依然处在懵逼状态。所以,抛开教程的顺序,从创建三维世界的角度去理解。
首先,我默认你是对html,js,css是有一定的使用经验。那么都知道html是文档流和文本流,载体内容是文字,当然你可以使用css把盒子模型编写得带有3D效果,但也仅限于一点透视效果而已。思考一下,想要完全自由创作3D物体,需要是什么载体?对,就是画布,不用想太复杂,毕竟电脑屏幕相对人来说是二维面,没有真实世界里面那种类似陶艺的纯三维世界去给你创造。画就可以在二维世界上表现出三维效果。好巧不巧,html上还真有一种画布标签结构
2) 渲染
好,我们已经知道web端的3D开发就是把三维物体渲染到canvas画布上,那么三维物体呢,还是没讲呢!别急,在讲三维物体前,得先有三维世界,毕竟三维物体当然是存在与三维世界啦!
那么怎么定义这个三维世界?其实很简单,就叫场景,在three.js里面会有一个封装类Scene。创建完场景后,把场景Scene渲染到画布上,那么就算完成了一个三维世界的创建了吗?尽管这个世界啥都没有。不不不,还有一个问题没解决。就是你得去看这个三维世界,而不是一个抽象的世界。因此我们一个眼睛去看这个世界,看到这个世界的某一个块区域。这个眼睛在three.js里面叫摄像机Camera,我们渲染Scene的时候,同时需要把Camera一起渲染到画布上。否则,没有摄像机的话,在这个画布上,渲染的是三维世界的哪块区域还是全部区域出来呢。
所以在渲染这步里面,我们需要做的是创建Scene场景类对象和Camera摄像机类对象。然后提交给WebGLRenderer渲染类对象。
3)物体
好了,看这一步的标题,要到正文了。
在创建三维物体之前,我们先分析一下,现实世界的物体有什么特征,比如一个篮球,足球,保龄球。虽然我们都知道它们是球型体,但表面的外观和手感都会有各不相同。当然三维世界里可不止球型体,还有长方体,锥体,甚至奇奇怪怪体。所以在3D开发里面,需要把一个三维物体按特征分类拆分出来。
首先,型状,也就是几何结构,定义一个物体首先要定义这个物体是个什么几何体,在three.js里面定义为Geometry几何体类。其次,外观,也就是纹理贴图,物体表面是个什么图案之类的,在three.js里面定义为Texture纹理类。再者,手感,通俗讲就是,这个物体摸起来是光滑的,还是毛毛得,金属感还是其他之类的,也就是材质,在three.js里面定义为Material材质类。
一个物体的创建至少需要用到上面所说的三种特征:Geometry几何体类,Material材质类,Texture纹理类。当然实际开发上纹理类也是可以省的。拿这三个类是不是就可以创建出一个物体了呢?no no no,这三种类是特征,是可以复用的,比如木质材质你可以用在柜子上,也可以用在地板上,同理几何体也一样,创建了一个球型,既可以用于篮球,也可以用于足球。所以我们需要一个模型对象,在three.js里面也就是Mesh网格模型对象。
网格模型Mesh对象才是实实在在的物体,假如你创建了两个Geometry几何体对象,一个球型,一个正方体。同时还创建了一个Mesh对象,当你赋给球型Geometry时,那么这个Mesh对象就是一个球型,赋给正方体Geometry时,那么这个Mesh就是一个正方体。同理Material材质类和Texture纹理类也一样。
初次接触3D开发的朋友可能会有这种感觉,Geometry和Mesh容易搞混。这里再重点区分一下Geometry和Mesh,Mesh是一个实实在在的模型,它是什么性状取决于你赋给它的是什么样的Geometry,而Geometry不是物体,是特征,它是可以复用的,比如你想创建10个小球,那么只需要创建一个球型Geometry就可以了。但需要创建10个Mesh。
最后,创建完的三维物体,还需要添加到Scene场景里面,那么物体才算完整的创建完。
4)光线
到第三步,差不多已经完成了三维物体的创建。但当你兴致勃勃看你创建出来的三维物体时,你会发现,要么黑不溜秋,啥也看不见,要么这个物体的压根没有3D视觉,3D视觉全靠想象。这是因为没有光影,没有明暗的区分。现实世界里面我们也是靠光线的亮度产生明暗视觉差,才能感受到这个三维世界。所以我们需要添加光线类Light的对象添加到Scene场景里
5)动态
三维世界是允许我们通过不同角度去观看这个世界的,所以三维世界里面允许物体或者视角的变化,而产生这种的原理跟电影的原理是一样的,就是一帧一帧连续变化展示,从而形成动态变化的效果。而渲染后的canvas画布是一帧,因此需要对画布不断渲染渲染,形成一帧一帧变化。在webgl开发里面采用requestAnimationFrame这个方法去不断递归调用渲染的方法来实现。
以上就是用可能不太严谨但比较通俗也可能是比较废话的步骤去描述在three.js下的3D开发是怎样的一个逻辑。当然three.js里还有一些非必要但可以使得三维世界更真实的封装类,以及摄像机,光线,几何体等大类型里面又有很多种子类型,这里都没有介绍。网上也有各类教程,官网首页也有各种使用three.js技术的应用可供体验。希望这篇文章可以帮到你。