three

前言

其实在公司弄得东西还算多的,有涉及的一些技术上的东西我想都记录一下,防止下次再碰到有个印象和参考,这次的模型展示对我当时做的时候也是一个小小的挑战,但是在理解和阅读了大量相关的视频和教程文档之后,发现其实不难,这里说的不难就是那种基本用法,当然如果要学的很深,用得很广那还是很难的,我这里也是说的一些皮毛,针对我做的商品展览而言。

如何做一个3d模型的展示

这个问题是领导给我发出来的问题,我的脑海中第一想法那必然就是用到 threejs 开发了,这个插件用的广泛程度不用我再多说了,很多做页面3d渲染模型都会用到,而且支持很多种类的模型文件,包括贴图光源阴影等等。
拿到需求的时候是懵逼的,但是也没说那么不知所措,先上官方文档上看例子,自己对着例子模拟写一个差不多的,如果不行的话可以找度娘,再不行就 goo 一下就好了。经过不懈努力的查阅和动手操作,确定下面的基本展示用法,如果想要简单的展示,那用我这个没错了。

先简单的了解 three 的使用和基本原理

three 使用的时候需要几个必须的参数:
第一个就是场景 Sence 相当于一个舞台,在这里是布置场景物品,所以的东西都是建立在这个场景内的。
第二个就是相机 Carma 相当于观众的眼睛视角。
第三个就是几何体 Geometry 舞台的展示的东西,可以用模型替代。
第四个就是灯光 light 相当于舞台灯光。
第五个就是控制 Controls 相当于这出舞台剧的总导演

当然这个五个并不是缺一不可,但是总需要这些东西我们的模型才能不出意外的展示,然后你都不知道出问题在哪里。下面开始讲代码实现

新建canvas画布开始

<div class="three"></div>

<script src="./three.min.js"></script>
<script src="./OBJLoader.js"></script>
<script src="./MTLLoader.js"></script>
<script src="./OrbitControls.js"></script>
<script>
  function init() {
    // 设置一下舞台
    var scene = new THREE.Scene();
    // 舞台的颜色
    scene.background = new THREE.Color(0xdddddd);
  }
  window.onload = init;
</script>

设置相机的视角位置

相机的视角就跟人体的视角差不多,设置的参数大小可以调节看的远近和在哪个地方观看。
一般我们使用符合物理世界近大远小真实情况的透视相机 PerspectiveCamera ,还有一些特殊情况,需要远近大小是一样的,那就要用正交相机 OrthographicCamera

相机视角

// PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
// fov:视场角
// aspect:视场宽高比(一般用 画布宽/画布 高即可)
// near:能看多近
// far:能看多远
//这几个参数决定了哪些scene里的三维顶点会被渲染/绘制出来
var camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 5000);
camera.position.set(-9, -8, 233)

添加渲染场景

是否使用 WebGL 渲染还是 canvas 渲染,在设置一下画布的大小和缩放以及颜色透明或者有颜色。

var renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);

//设置背景为透明,这样就可以自己加背景图片了
renderer.setClearAlpha(0);
document.querySelector('.three').appendChild(renderer.domElement);

设置光源和位置

根据参数的不同,显示的光源的位置不一样,加入的光源环境不同,一般情况下直接使用平行光即可展示,显示模型自带的光。

//光源
var ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);

// 平行光
var directionalLight = new THREE.DirectionalLight(0xffffff, 1.5);
directionalLight.position.set(0, 1, 0);
scene.add(directionalLight);

设置手势控制

对于手势的控制,这里需要添加对应的插件 OrbitControls.js 即可操作。

//手势控制器
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.autoRotate = true;
controls.enablePan = false;
controls.update();

最后再加上关键的模型

其实加模型或者几何体都可以,但我们大部分场景都是用到做好的3d模型,拿到这个模型之后直接渲染就OK了,对上需要解析模型的插件 OBJLoader 和贴图插件 MTLLoader 渲染。这里我用的是 obj 格式的模型,如果是其他模式,也可以选择其他的模式的解析插件即可。

var mtlLoader = new THREE.MTLLoader();
var objLoader = new THREE.OBJLoader();
mtlLoader.load(
  'model.mtl',
  function (materials) {
    materials.preload();
    objLoader.setMaterials(materials).load(
      'model.obj',
      function (obj) {
        scene.add(obj);
        // 给模型加一个旋转的动画
        animate();
      },
      function (xhr) {
        console.log(xhr.loaded / xhr.total * 100);
      },
      function (error) {
        console.error(error);
      }
    )
  }
)

function animate() {
  requestAnimationFrame(animate);
  controls.update();
  renderer.render(scene, camera);
}

至此如果模型正确,那么刷新浏览器就可以直接看到了。可以看一下 预览