您的当前位置:首页正文

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

2020-11-27 来源:意榕旅游网
本篇文章主要介绍了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如何实现音频播放功能

显示全文