• 技术文章 >web前端 >js教程

    在three.js中如何实现3D模型展示

    亚连亚连2018-06-14 15:09:03原创2635
    本篇文章主要介绍了three.js实现3D模型展示的示例代码,现在分享给大家,也给大家做个参考。

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

    先看看效果:

    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()">
    <p id="Loading" style="color:#fff">Loading...</p>
    </body>
    </html>

    哦 我的文件结构

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

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

    上面是我整理给大家的,希望今后会对大家有帮助。

    相关文章:

    使用tangram.js库如何实现js类

    利用js代码如何实现复制功能

    使用JavaScript如何实现音频播放功能

    以上就是在three.js中如何实现3D模型展示的详细内容,更多请关注php中文网其它相关文章!

    声明:本文原创发布php中文网,转载请注明出处,感谢您的尊重!如有疑问,请联系admin@php.cn处理
    专题推荐:three.js 3D模型展示
    上一篇:在jQuery中如何获取数据赋值给页面 下一篇:在Vuejs中通过nextTick()实现异步更新队列
    大前端线上培训班

    相关文章推荐

    • innerhtml是jquery方法么• javascript怎么设置标签的背景颜色• jquery select 不可编辑怎么办• javascript 怎么将时间转毫秒• 浅谈怎么利用node提升工作效率

    全部评论我要评论

  • 心若朝阳

    优秀,666,谢谢楼主

    2019-08-16

  • ぞfortomorrowあ

    楼主,您好,three.js里面不是要引入很多文件吗,我看你的代码没有引入哦,并且我复制你的代码,然后修改了一点,但是不成功,显示不出来物体,求助楼主,谢谢

    2019-10-28

  • 越努力越幸运

    大神,我想要你的所有文件

    2019-12-05

  • Gary

    大神,我也想要你的所有文件

    2019-12-14

  • Pamper.

    求文件,感恩楼主

    2020-04-24

  • 取消发布评论发送
  • 1/1

    PHP中文网