three.js实现3D模型展示的示例代码


Posted in Javascript onDecember 31, 2017

由于项目需要展示3d模型,所以对three做了点研究,分享出来 希望能帮到大家

先看看效果:

three.js实现3D模型展示的示例代码 

three.js整体来说 不是很难 只要你静下心来研究研究 很快就会上手的

首先我们在页面上需要创建一个能够放置3D模型的画布 也可以说是初始化 Three

var WIDTH,HEIGHT;
  var  renderer;
  function initThree() {
    WIDTH = document.documentElement.clientWidth/2; <!--{foreach from=$recommended_goods item=rgoods}--> <!-- {/foreach} -->
    HEIGHT = document.documentElement.clientHeight/2;
    /* 渲染器 */
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(WIDTH , HEIGHT);
    renderer.setClearColor(new THREE.Color(0x66666));
    renderer.gammaInput = true;
    renderer.gammaOutput = true;

    document.body.appendChild(renderer.domElement);
  }

通过上面的代码不难看出 我们设置了 在body里追加了一块画布 宽高是 client的一半颜色为 0x66666 这里要注意的是  renderer = new THREE.WebGLRenderer(); 因为我们所有的设置都是以renderer为对象设置

下来 我们需要调整摄像头 即视觉角度

/* 摄像头 */
  var camera;
  function initCamera() {
    var VIEW_ANGLE = 45,
        ASPECT = WIDTH / HEIGHT,
        NEAR = 0.1,
        FAR = 10000;
    camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
    camera.position.set(20, 0, 0);
    //设置视野的中心坐标
    camera.lookAt(scene.position);
  }

以上代码主要是控制视觉角度 数值可以在后期根据自己的需求去调整

加载场景:

/* 场景 */
   var scene;
   function initScene() {
     scene = new THREE.Scene();
   }

加载灯光效果

/* 灯光 */
  var light,light2,light3;
  function initLight() {
    //平行光
    light = new THREE.DirectionalLight(0xFFFFFF);
    light.position.set(0, 99, 0).normalize();
    scene.add(light);
    //环境光
    light2 = new THREE.AmbientLight(0x999999);
    scene.add(light2);
    //点光源
    light3 = new THREE.PointLight(0x00FF00);
    light3.position.set(300, 0, 0);
    scene.add(light3);
  }

显示模型对象:

/* 显示对象 */
  var cube;
  function initObject(){
    // ASCII file
    var loader = new THREE.STLLoader();
    loader.addEventListener( 'load', function ( event ) {
      var loading = document.getElementById("Loading");
      loading.parentNode.removeChild(loading);
      var geometry = event.content;
      //砖红色
      var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200 } );
      //纯黑色
//      var material = new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'http://localhost:8080/textures/metal.jpg', new THREE.SphericalReflectionMapping() ), overdraw: true } ) ;
      //粉色 带阴影
//      var material = new THREE.MeshLambertMaterial( { color:0xff5533, side: THREE.DoubleSide } );
      //灰色
//      var material = new THREE.MeshLambertMaterial({color: 000000});  //材质设定 (颜色)
      var mesh = new THREE.Mesh( geometry, material );
      var center = THREE.GeometryUtils.center(geometry);
      var boundbox=geometry.boundingBox;
      var vector3 = boundbox.size(null);
      var vector3 = boundbox.size(null);
      console.log(vector3);
      var scale = vector3.length();
      camera.position.set(scale, 0, 0);
      camera.lookAt(scene.position);
      scene.add(camera);
      //利用一个轴对象以可视化的3轴以简单的方式。X轴是红色的。Y轴是绿色的。Z轴是蓝色的。这有助于理解在空间的所有三个轴的方向。
      var axisHelper = new THREE.AxisHelper(800);
      scene.add(axisHelper);

      //周围边框
      bboxHelper = new THREE.BoxHelper();
      bboxHelper.visible = true;
      var meshMaterial = material;
      mainModel = new THREE.Mesh(geometry, meshMaterial);
      bboxHelper.update(mainModel);
      bboxHelper.geometry.computeBoundingBox();
      scene.add(bboxHelper);

      //地板网格
//      var gridHelper = new THREE.GridHelper(500, 40); // 500 is grid size, 20 is grid step
//      gridHelper.position = new THREE.Vector3(0, 0, 0);
//      gridHelper.rotation = new THREE.Euler(0, 0, 0);
//      scene.add(gridHelper);
//      var gridHelper2 = gridHelper.clone();
//      gridHelper2.rotation = new THREE.Euler(Math.PI / 2, 0, 0);
//      scene.add(gridHelper2);
//      var gridHelper3 = gridHelper.clone();
//      gridHelper3.rotation = new THREE.Euler(Math.PI / 2, 0, Math.PI / 2);
//      scene.add(gridHelper3);
//
//      var grid = new THREE.GridHelper(300, 40, 25, [0, 0, 1], 0x000055, 0.2, true, "#FFFFFF", "left");
//      scene.add(grid);
      var x = (boundbox.max.x - boundbox.min.x).toFixed(2);
      var y = (boundbox.max.y - boundbox.min.y).toFixed(2);
      var z = (boundbox.max.z - boundbox.min.z).toFixed(2);
      console.log(x);
      console.log(y);
      console.log(z);
      console.log(boundbox);
      mesh.position.set(0,0,0);
//      mesh.position.x = scene.position.x;
//      mesh.position.y = scene.position.y ;
//      mesh.position.z = scene.position.z;
      scene.add(mesh);
      renderer.clear();
      renderer.render(scene, camera);
    } );
    loader.load( '3dfile/莫比乌斯环.STL' );
  }

这里根据文件类型选择相对应的js引入即可 我加载的是STL模型 所以我引入的是 STLLoader.js

<script src="js/STLLoader.js"></script>

如果需要显示网格标尺 将 网格部分代码 去掉注释即可

下来是控制方法 (虽然我没有在显示代码里面写根据键盘按键放大缩小 但还是提供给大家 参考)

//控制
  var effect;
  var controls;
  function initControl(){
    effect = new THREE.AsciiEffect( renderer );
    effect.setSize( WIDTH, HEIGHT );
    controls = new THREE.TrackballControls( camera,renderer.domElement);
  }

最后就是一个初始调用了

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

  function threeStart() {
    initThree();
    initScene();
    initCamera();
    initLight();
    initObject();
    initControl();
    animate();
  }

附上完整代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>WebGL</title>
  <script type="text/javascript" charset="utf-8" src="js/three.js"></script>
  <script src="js/STLLoader.js"></script>
  <script src="js/TrackballControls.js"></script>
  <script src="js/AsciiEffect.js"></script>
  <style>body{overflow:hidden;background:#eee}</style>
</head>
<script>
  var WIDTH,HEIGHT;
  var renderer;
  function initThree() {
    WIDTH = document.documentElement.clientWidth/2; <!--{foreach from=$recommended_goods item=rgoods}--> <!-- {/foreach} -->
    HEIGHT = document.documentElement.clientHeight/2;
    /* 渲染器 */
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(WIDTH , HEIGHT);
    renderer.setClearColor(new THREE.Color(0x66666));
    renderer.gammaInput = true;
    renderer.gammaOutput = true;

    document.body.appendChild(renderer.domElement);
  }

  /* 摄像头 */
  var camera;
  function initCamera() {
    var VIEW_ANGLE = 45,
        ASPECT = WIDTH / HEIGHT,
        NEAR = 0.1,
        FAR = 10000;
    camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
    camera.position.set(20, 0, 0);
    //设置视野的中心坐标
    camera.lookAt(scene.position);
  }

  /* 场景 */
  var scene;
  function initScene() {
    scene = new THREE.Scene();
  }

  /* 灯光 */
  var light,light2,light3;
  function initLight() {
    //平行光
    light = new THREE.DirectionalLight(0xFFFFFF);
    light.position.set(0, 99, 0).normalize();
    scene.add(light);
    //环境光
    light2 = new THREE.AmbientLight(0x999999);
    scene.add(light2);
    //点光源
    light3 = new THREE.PointLight(0x00FF00);
    light3.position.set(300, 0, 0);
    scene.add(light3);
  }

  /* 显示对象 */
  var cube;
  function initObject(){
    // ASCII file
    var loader = new THREE.STLLoader();
    loader.addEventListener( 'load', function ( event ) {
      var loading = document.getElementById("Loading");
      loading.parentNode.removeChild(loading);
      var geometry = event.content;
      //砖红色
      var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200 } );
      //纯黑色
//      var material = new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'http://localhost:8080/textures/metal.jpg', new THREE.SphericalReflectionMapping() ), overdraw: true } ) ;
      //粉色 带阴影
//      var material = new THREE.MeshLambertMaterial( { color:0xff5533, side: THREE.DoubleSide } );
      //灰色
//      var material = new THREE.MeshLambertMaterial({color: 000000});  //材质设定 (颜色)
      var mesh = new THREE.Mesh( geometry, material );
      var center = THREE.GeometryUtils.center(geometry);
      var boundbox=geometry.boundingBox;
      var vector3 = boundbox.size(null);
      var vector3 = boundbox.size(null);
      console.log(vector3);
      var scale = vector3.length();
      camera.position.set(scale, 0, 0);
      camera.lookAt(scene.position);
      scene.add(camera);

      //利用一个轴对象以可视化的3轴以简单的方式。X轴是红色的。Y轴是绿色的。Z轴是蓝色的。这有助于理解在空间的所有三个轴的方向。
      var axisHelper = new THREE.AxisHelper(800);
      scene.add(axisHelper);

      //周围边框
      bboxHelper = new THREE.BoxHelper();
      bboxHelper.visible = true;
      var meshMaterial = material;
      mainModel = new THREE.Mesh(geometry, meshMaterial);
      bboxHelper.update(mainModel);
      bboxHelper.geometry.computeBoundingBox();
      scene.add(bboxHelper);

      //地板网格
//      var gridHelper = new THREE.GridHelper(500, 40); // 500 is grid size, 20 is grid step
//      gridHelper.position = new THREE.Vector3(0, 0, 0);
//      gridHelper.rotation = new THREE.Euler(0, 0, 0);
//      scene.add(gridHelper);
//      var gridHelper2 = gridHelper.clone();
//      gridHelper2.rotation = new THREE.Euler(Math.PI / 2, 0, 0);
//      scene.add(gridHelper2);
//      var gridHelper3 = gridHelper.clone();
//      gridHelper3.rotation = new THREE.Euler(Math.PI / 2, 0, Math.PI / 2);
//      scene.add(gridHelper3);
//
//      var grid = new THREE.GridHelper(300, 40, 25, [0, 0, 1], 0x000055, 0.2, true, "#FFFFFF", "left");
//      scene.add(grid);
      var x = (boundbox.max.x - boundbox.min.x).toFixed(2);
      var y = (boundbox.max.y - boundbox.min.y).toFixed(2);
      var z = (boundbox.max.z - boundbox.min.z).toFixed(2);
      console.log(x);
      console.log(y);
      console.log(z);
      console.log(boundbox);
      mesh.position.set(0,0,0);
//      mesh.position.x = scene.position.x;
//      mesh.position.y = scene.position.y ;
//      mesh.position.z = scene.position.z;
      scene.add(mesh);


      renderer.clear();
      renderer.render(scene, camera);
    } );
    loader.load( '3dfile/莫比乌斯环.STL' );
  }

  //控制
  var effect;
  var controls;
  function initControl(){
    effect = new THREE.AsciiEffect( renderer );
    effect.setSize( WIDTH, HEIGHT );
    controls = new THREE.TrackballControls( camera,renderer.domElement);
  }

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

  function threeStart() {
    initThree();
    initScene();
    initCamera();
    initLight();
    initObject();
    initControl();
    animate();
  }
</script>
<body onload="threeStart()">
<div id="Loading" style="color:#fff">Loading...</div>
</body>
</html>

哦 我的文件结构

three.js实现3D模型展示的示例代码

如果想要所有文件的小伙伴 给我留言即可 

three.js实现3D模型展示的示例代码

补充一点,由于在显示模型的方法里我加入了 bboxHelper = new THREE.BoxHelper() 所以我们可以获取到模型的 X Y Z三轴的尺寸 也可以当作 模型的长宽高 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery选择器中含有空格的使用示例及注意事项
Aug 25 Javascript
jquery实现多屏多图焦点图切换特效的方法
May 04 Javascript
简单谈谈Javascript中类型的判断
Oct 19 Javascript
Vue.js系列之项目搭建(1)
Jan 03 Javascript
微信小程序 特效菜单抽屉效果实例代码
Jan 11 Javascript
CodeMirror js代码加亮使用总结
Mar 25 Javascript
jquery.validate表单验证插件使用详解
Jun 21 jQuery
js删除数组中的元素delete和splice的区别详解
Feb 03 Javascript
vue+express+jwt持久化登录的方法
Jun 14 Javascript
微信小程序单选框自定义赋值
May 26 Javascript
JavaScript Image对象实现原理实例解析
Aug 26 Javascript
关于IDEA中的.VUE文件报错 Export declarations are not supported by current JavaScript version
Oct 17 Javascript
浅谈Vuejs中nextTick()异步更新队列源码解析
Dec 31 #Javascript
Angular 开发学习之Angular CLI的安装使用
Dec 31 #Javascript
ReactNative实现Toast的示例
Dec 31 #Javascript
简单谈谈CommonsChunkPlugin抽取公共模块
Dec 31 #Javascript
AngularJS基于MVC的复杂操作实例讲解
Dec 31 #Javascript
jQuery实现页码跳转式动态数据分页
Dec 31 #jQuery
React数据传递之组件内部通信的方法
Dec 31 #Javascript
You might like
php数组函数序列之array_key_exists() - 查找数组键名是否存在
2011/10/29 PHP
php 模拟GMAIL,HOTMAIL(MSN),YAHOO,163,126邮箱登录的详细介绍
2013/06/18 PHP
PHP实现多图片上传类实例
2014/07/26 PHP
php开发工具有哪五款
2015/11/09 PHP
PHP微信刮刮卡 附微信接口
2016/07/22 PHP
php封装一个异常的处理类
2017/06/08 PHP
菜单效果
2006/10/14 Javascript
2则自己编写的jQuery特效分享
2015/02/26 Javascript
表单中单选框添加选项和移除选项
2016/07/04 Javascript
初识NodeJS服务端开发入门(Express+MySQL)
2017/04/07 NodeJs
深入理解Webpack 中路径的配置
2017/06/17 Javascript
AngularJS实现页面跳转后自动弹出对话框实例代码
2017/08/02 Javascript
剖析Angular Component的源码示例
2018/03/23 Javascript
Puppeteer 爬取动态生成的网页实战
2018/11/14 Javascript
ES6基础之字符串和函数的拓展详解
2019/08/22 Javascript
electron-vue开发环境内存泄漏问题汇总
2019/10/10 Javascript
vue2.x 通过后端接口代理,获取qq音乐api的数据示例
2019/10/30 Javascript
js 图片懒加载的实现
2020/10/21 Javascript
python中判断文件编码的chardet(实例讲解)
2017/12/21 Python
Python实现定制自动化业务流量报表周报功能【XlsxWriter模块】
2019/03/11 Python
python基于SMTP协议发送邮件
2019/05/31 Python
python 如何将数据写入本地txt文本文件的实现方法
2019/09/11 Python
Pytorch.nn.conv2d 过程验证方式(单,多通道卷积过程)
2020/01/03 Python
详解vscode实现远程linux服务器上Python开发
2020/11/10 Python
利用python爬取有道词典的方法
2020/12/08 Python
python中类与对象之间的关系详解
2020/12/16 Python
纯CSS3制作的鼠标悬停时边框旋转
2017/01/03 HTML / CSS
卡西欧G-SHOCK英国官网: 防水防震手表
2018/01/08 全球购物
.NET remoting的两种通道是什么
2016/05/31 面试题
Linux管理员面试经常问道的相关命令
2013/04/29 面试题
工作时间擅自离岗检讨书
2014/10/24 职场文书
2015年公司保安年终工作总结
2015/05/14 职场文书
《好妈妈胜过好老师》:每个孩子的优秀都是有源头的
2020/01/03 职场文书
Mac M1安装mnmp (Mac+Nginx+MySQL+PHP) 开发环境
2021/03/29 PHP
golang特有程序结构入门教程
2021/06/02 Python
HTML+JS实现在线朗读器
2022/02/15 Javascript