three.js实现3D模型展示

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

先看看效果:

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

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

 1 var WIDTH,HEIGHT;
 2     var    renderer;
 3     function initThree() {
 4         WIDTH = document.documentElement.clientWidth/2; <!--{foreach from=$recommended_goods item=rgoods}--> <!-- {/foreach} -->
 5         HEIGHT = document.documentElement.clientHeight/2;
 6         /* 渲染器 */
 7         renderer = new THREE.WebGLRenderer();
 8         renderer.setSize(WIDTH , HEIGHT);
 9         renderer.setClearColor(new THREE.Color(0x66666));
10         renderer.gammaInput = true;
11         renderer.gammaOutput = true;
12 
13         document.body.appendChild(renderer.domElement);
14     }

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

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

 1 /* 摄像头 */
 2     var camera;
 3     function initCamera() {
 4         var VIEW_ANGLE = 45,
 5                 ASPECT = WIDTH / HEIGHT,
 6                 NEAR = 0.1,
 7                 FAR = 10000;
 8         camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
 9         camera.position.set(20, 0, 0);
10         //设置视野的中心坐标
11         camera.lookAt(scene.position);
12     }

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

加载场景:

1     /* 场景 */
2     var scene;
3     function initScene() {
4         scene = new THREE.Scene();
5     }

加载灯光效果

 1 /* 灯光 */
 2     var light,light2,light3;
 3     function initLight() {
 4         //平行光
 5         light = new THREE.DirectionalLight(0xFFFFFF);
 6         light.position.set(0, 99, 0).normalize();
 7         scene.add(light);
 8         //环境光
 9         light2 = new THREE.AmbientLight(0x999999);
10         scene.add(light2);
11         //点光源
12         light3 = new THREE.PointLight(0x00FF00);
13         light3.position.set(300, 0, 0);
14         scene.add(light3);
15     }

显示模型对象:

 1     /* 显示对象 */
 2     var cube;
 3     function initObject(){
 4         // ASCII file
 5         var loader = new THREE.STLLoader();
 6 
 7         loader.addEventListener( 'load', function ( event ) {
 8             var loading = document.getElementById("Loading");
 9             loading.parentNode.removeChild(loading);
10             var geometry = event.content;
11             //砖红色
12             var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200 } );
13             //纯黑色
14 //            var material = new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'http://localhost:8080/textures/metal.jpg', new THREE.SphericalReflectionMapping() ), overdraw: true } ) ;
15             //粉色 带阴影
16 //            var material = new THREE.MeshLambertMaterial( { color:0xff5533, side: THREE.DoubleSide } );
17             //灰色
18 //            var material = new THREE.MeshLambertMaterial({color: 000000});    //材质设定  (颜色)
19 
20 
21             var mesh = new THREE.Mesh( geometry, material );
22 
23             var center = THREE.GeometryUtils.center(geometry);
24             var boundbox=geometry.boundingBox;
25             var vector3 = boundbox.size(null);
26             var vector3 = boundbox.size(null);
27             console.log(vector3);
28             var scale = vector3.length();
29             camera.position.set(scale, 0, 0);
30             camera.lookAt(scene.position);
31             scene.add(camera);
32 
33 
34             //利用一个轴对象以可视化的3轴以简单的方式。X轴是红色的。Y轴是绿色的。Z轴是蓝色的。这有助于理解在空间的所有三个轴的方向。
35             var axisHelper = new THREE.AxisHelper(800);
36             scene.add(axisHelper);
37 
38             //周围边框
39             bboxHelper = new THREE.BoxHelper();
40             bboxHelper.visible = true;
41             var meshMaterial = material;
42             mainModel = new THREE.Mesh(geometry, meshMaterial);
43             bboxHelper.update(mainModel);
44             bboxHelper.geometry.computeBoundingBox();
45             scene.add(bboxHelper);
46 
47             //地板网格
48 //            var gridHelper = new THREE.GridHelper(500, 40); // 500 is grid size, 20 is grid step
49 //            gridHelper.position = new THREE.Vector3(0, 0, 0);
50 //            gridHelper.rotation = new THREE.Euler(0, 0, 0);
51 //            scene.add(gridHelper);
52 //            var gridHelper2 = gridHelper.clone();
53 //            gridHelper2.rotation = new THREE.Euler(Math.PI / 2, 0, 0);
54 //            scene.add(gridHelper2);
55 //            var gridHelper3 = gridHelper.clone();
56 //            gridHelper3.rotation = new THREE.Euler(Math.PI / 2, 0, Math.PI / 2);
57 //            scene.add(gridHelper3);
58 //
59 //            var grid = new THREE.GridHelper(300, 40, 25, [0, 0, 1], 0x000055, 0.2, true, "#FFFFFF", "left");
60 //            scene.add(grid);
61 
62 
63             var x = (boundbox.max.x - boundbox.min.x).toFixed(2);
64             var y = (boundbox.max.y - boundbox.min.y).toFixed(2);
65             var z = (boundbox.max.z - boundbox.min.z).toFixed(2);
66 
67             console.log(x);
68             console.log(y);
69             console.log(z);
70             console.log(boundbox);
71 
72             mesh.position.set(0,0,0);
73 //            mesh.position.x = scene.position.x;
74 //            mesh.position.y = scene.position.y ;
75 //            mesh.position.z = scene.position.z;
76             scene.add(mesh);
77 
78 
79             renderer.clear();
80             renderer.render(scene, camera);
81         } );
82         loader.load( '3dfile/莫比乌斯环.STL' );
83     }

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

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

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

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

1 //控制
2     var effect;
3     var controls;
4     function initControl(){
5         effect = new THREE.AsciiEffect( renderer );
6         effect.setSize( WIDTH, HEIGHT );
7         controls = new THREE.TrackballControls( camera,renderer.domElement);
8     }

最后就是一个初始调用了

 1   function animate() {
 2         requestAnimationFrame( animate );
 3         controls.update();
 4         effect.render( scene, camera );
 5     }
 6 
 7     function threeStart() {
 8         initThree();
 9         initScene();
10         initCamera();
11         initLight();
12         initObject();
13         initControl();
14         animate();
15     }

附上完整代码

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4     <meta charset="UTF-8" />
  5     <title>WebGL</title>
  6     <script type="text/javascript" charset="utf-8" src="js/three.js"></script>
  7     <script src="js/STLLoader.js"></script>
  8     <script src="js/TrackballControls.js"></script>
  9     <script src="js/AsciiEffect.js"></script>
 10     <style>body{overflow:hidden;background:#eee}</style>
 11 </head>
 12 <script>
 13     var WIDTH,HEIGHT;
 14     var    renderer;
 15     function initThree() {
 16         WIDTH = document.documentElement.clientWidth/2; <!--{foreach from=$recommended_goods item=rgoods}--> <!-- {/foreach} -->
 17         HEIGHT = document.documentElement.clientHeight/2;
 18         /* 渲染器 */
 19         renderer = new THREE.WebGLRenderer();
 20         renderer.setSize(WIDTH , HEIGHT);
 21         renderer.setClearColor(new THREE.Color(0x66666));
 22         renderer.gammaInput = true;
 23         renderer.gammaOutput = true;
 24 
 25         document.body.appendChild(renderer.domElement);
 26     }
 27 
 28     /* 摄像头 */
 29     var camera;
 30     function initCamera() {
 31         var VIEW_ANGLE = 45,
 32                 ASPECT = WIDTH / HEIGHT,
 33                 NEAR = 0.1,
 34                 FAR = 10000;
 35         camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
 36         camera.position.set(20, 0, 0);
 37         //设置视野的中心坐标
 38         camera.lookAt(scene.position);
 39     }
 40 
 41     /* 场景 */
 42     var scene;
 43     function initScene() {
 44         scene = new THREE.Scene();
 45     }
 46 
 47     /* 灯光 */
 48     var light,light2,light3;
 49     function initLight() {
 50         //平行光
 51         light = new THREE.DirectionalLight(0xFFFFFF);
 52         light.position.set(0, 99, 0).normalize();
 53         scene.add(light);
 54         //环境光
 55         light2 = new THREE.AmbientLight(0x999999);
 56         scene.add(light2);
 57         //点光源
 58         light3 = new THREE.PointLight(0x00FF00);
 59         light3.position.set(300, 0, 0);
 60         scene.add(light3);
 61     }
 62 
 63     /* 显示对象 */
 64     var cube;
 65     function initObject(){
 66         // ASCII file
 67         var loader = new THREE.STLLoader();
 68 
 69         loader.addEventListener( 'load', function ( event ) {
 70             var loading = document.getElementById("Loading");
 71             loading.parentNode.removeChild(loading);
 72             var geometry = event.content;
 73             //砖红色
 74             var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200 } );
 75             //纯黑色
 76 //            var material = new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'http://localhost:8080/textures/metal.jpg', new THREE.SphericalReflectionMapping() ), overdraw: true } ) ;
 77             //粉色 带阴影
 78 //            var material = new THREE.MeshLambertMaterial( { color:0xff5533, side: THREE.DoubleSide } );
 79             //灰色
 80 //            var material = new THREE.MeshLambertMaterial({color: 000000});    //材质设定  (颜色)
 81 
 82 
 83             var mesh = new THREE.Mesh( geometry, material );
 84 
 85             var center = THREE.GeometryUtils.center(geometry);
 86             var boundbox=geometry.boundingBox;
 87             var vector3 = boundbox.size(null);
 88             var vector3 = boundbox.size(null);
 89             console.log(vector3);
 90             var scale = vector3.length();
 91             camera.position.set(scale, 0, 0);
 92             camera.lookAt(scene.position);
 93             scene.add(camera);
 94 
 95 
 96             //利用一个轴对象以可视化的3轴以简单的方式。X轴是红色的。Y轴是绿色的。Z轴是蓝色的。这有助于理解在空间的所有三个轴的方向。
 97             var axisHelper = new THREE.AxisHelper(800);
 98             scene.add(axisHelper);
 99 
100             //周围边框
101             bboxHelper = new THREE.BoxHelper();
102             bboxHelper.visible = true;
103             var meshMaterial = material;
104             mainModel = new THREE.Mesh(geometry, meshMaterial);
105             bboxHelper.update(mainModel);
106             bboxHelper.geometry.computeBoundingBox();
107             scene.add(bboxHelper);
108 
109             //地板网格
110 //            var gridHelper = new THREE.GridHelper(500, 40); // 500 is grid size, 20 is grid step
111 //            gridHelper.position = new THREE.Vector3(0, 0, 0);
112 //            gridHelper.rotation = new THREE.Euler(0, 0, 0);
113 //            scene.add(gridHelper);
114 //            var gridHelper2 = gridHelper.clone();
115 //            gridHelper2.rotation = new THREE.Euler(Math.PI / 2, 0, 0);
116 //            scene.add(gridHelper2);
117 //            var gridHelper3 = gridHelper.clone();
118 //            gridHelper3.rotation = new THREE.Euler(Math.PI / 2, 0, Math.PI / 2);
119 //            scene.add(gridHelper3);
120 //
121 //            var grid = new THREE.GridHelper(300, 40, 25, [0, 0, 1], 0x000055, 0.2, true, "#FFFFFF", "left");
122 //            scene.add(grid);
123 
124 
125             var x = (boundbox.max.x - boundbox.min.x).toFixed(2);
126             var y = (boundbox.max.y - boundbox.min.y).toFixed(2);
127             var z = (boundbox.max.z - boundbox.min.z).toFixed(2);
128 
129             console.log(x);
130             console.log(y);
131             console.log(z);
132             console.log(boundbox);
133 
134             mesh.position.set(0,0,0);
135 //            mesh.position.x = scene.position.x;
136 //            mesh.position.y = scene.position.y ;
137 //            mesh.position.z = scene.position.z;
138             scene.add(mesh);
139 
140 
141             renderer.clear();
142             renderer.render(scene, camera);
143         } );
144         loader.load( '3dfile/莫比乌斯环.STL' );
145     }
146 
147     //控制
148     var effect;
149     var controls;
150     function initControl(){
151         effect = new THREE.AsciiEffect( renderer );
152         effect.setSize( WIDTH, HEIGHT );
153         controls = new THREE.TrackballControls( camera,renderer.domElement);
154     }
155 
156     function animate() {
157         requestAnimationFrame( animate );
158         controls.update();
159         effect.render( scene, camera );
160     }
161 
162     function threeStart() {
163         initThree();
164         initScene();
165         initCamera();
166         initLight();
167         initObject();
168         initControl();
169         animate();
170     }
171 </script>
172 <body onload="threeStart()">
173 <div id="Loading" style="color:#fff">Loading...</div>
174 </body>
175 </html>

哦 我的文件结构

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

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

原文地址:https://www.cnblogs.com/we-jack/p/8145457.html