前言
最近无意中刷到了国外的一个3D模型网站(https://sketchfab.com),被里面各种各样的模型吸引了。
于是就有了想试试在自己的网页上把模型加载出来的想法,这需要借助一个强大的且好用的web3D加载引擎-------Three.js,(中文文档:http://www.webgl3d.cn/Three.js)。
那么Three.js是什么呢?
官方给出的定义是,Three.js是基于原生WebGL封装运行的三维引擎,在所有WebGL引擎中,Three.js是国内文资料最多、使用最广泛的三维引擎。
在浏览器不支持WebGL技术的时代,如果你想在网页上展示一款产品往往是通过2D图片的形式实现。
如果想3D展示一个产品,往往依赖于OpenGL技术,比如通过unity3D或ue4开发一个桌面应用,这样做往往很难随意传播,需要用户下载程序很麻烦,如果是通过Web的方式展示产品的三维模型,一个超链接就可以随意传播。
随着WebGL技术的持续推广,5G技术的持续推广,各种产品在线3D展示将会变得越来越普及,目前 three.js 可以应用在很多的领域,具体的就不一一赘述了,这一点官方文档已经讲述的很清楚了。
PS:Three.js底层是WebGL,当然这也不意味着,学习threejs之前,一定要先学习WebGL。一方面简单的项目,你可以不用学习WebGL, 另一个学习方面WebGL对图形学方面理论要求高,可以选择先学习Three.js,等需要学习WebGL的时候,在学习也不晚。
准备工作
下面我们就结合着文档做一个简单的demo吧。既然要做模型的3D网页渲染展示,我们就需要一个模型文件。我们进入到之前提到过的模型网站去挑选一个自己喜欢的模型下载下来(这里面有付费的模型,如果喜欢一些付费的自己可以随意购买)。
我选择了一个免费的悍马汽车模型,模型文件的格式上,我选择了GITF格式的,后面会使用到three.js官方封装的GITF格式的加载器。
项目开始
简单介绍一下项目结构,如下图所示
其中three.js也可使用cdn公开的加速版,就可以不用下载下来了
<script src="https://cdn.bootcdn.net/ajax/libs/three.js/r128/three.min.js"></script>
模型加载器是从官方的GitHub上找的:
https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/GLTFLoader.js
相机控制器也是从官方的GitHub找的:
https://github.com/mrdoob/three.js/blob/dev/examples/js/controls/OrbitControls.js
有了这几个文件我们就可以准备编写了
首先我们需要一个web页面去集成并呈现模型相关的文件代码入下(indexs.html):
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8 <style> 9 body{ 10 margin: 0; 11 } 12 </style> 13 </head> 14 <body> 15 <script src="https://cdn.bootcdn.net/ajax/libs/three.js/r128/three.min.js"></script> 16 <script src="GLTFLoader.js"></script> 17 <script src="OrbitControls.js" ></script> 18 <script src="app.js"></script> 19 </body> 20 </html>
然后就是构建我们的app.js初始化函数相关的内容了,具体代码入下:
/* @scene:场景 @camera:相机 @spotLight:场景光源 @renderer:模型加载器 */ let scene,camera,renderer,spotLight; const init =()=>{ //创建场景(场景就像一个看不到边际的宇宙空间) scene = new THREE.Scene(); scene.background = new THREE.Color(0xffffff); // 渲染器 renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMapEnabled = true; //console.log(renderer.domElement) document.body.appendChild(renderer.domElement); //相机 (我们在场景的观察位置) const aspect = window.innerWidth / window.innerHeight; camera = new THREE.PerspectiveCamera(60, aspect, 0.01, 5000); camera.rotation.y = (90 / 180) * Math.PI; camera.position.set(4.8, 3); //场景光源 (场景的光源位置,类似聚光灯,或者宇宙中的太阳) const ambientLight = new THREE.AmbientLight(0xffffff); scene.add(ambientLight) //灯光属性 spotLight = new THREE.SpotLight(0xffffff); spotLight.castShadow = true; spotLight.shadowCameraVisible = true; spotLight.position.set(10,10,10); //设置阴影贴图精度 spotLight.shadowMapWidth = spotLight.shadowMapHeight = 1024*4; scene.add(spotLight); //相机控制(让相机的视角可以根据鼠标的拖拽自由切换) const controls = new THREE.OrbitControls(camera, renderer.domElement); controls.addEventListener("change", renderer); //模型加载器 const loader = new THREE.GLTFLoader(); //bmw_735i hummer_h2 loader.load("./model/hummer_h2/scene.gltf",(result) =>{ scene.add(result.scene); animate(); //renderer.render(scene,camera); }); }; //使得相机在切换视角时不断更新当前视角下的模型姿态 const animate = () =>{ renderer.render(scene,camera); requestAnimationFrame(animate) } //最后初始化 init();
呈现效果
整体来看,呈现的效果还是不错的。
最后
这只是Three.js的冰山一角,仅仅是功能的初步尝鲜,如果想深入学习,还需要补充模型建模相关的知识,以及对three.js的深入理解与实践。
three.js在 WEB 3d展示上的功能非常强大,在未来会应用的越来越广泛。