如何在vue中使用three.js并实现基本模型的加载与动画实现

1.安装three.js

npm install three --save

2.导入three以及项目所需要的模块

import * as THREE from “three/build/three.module.js”;
import Stats from “three/examples/jsm/libs/stats.module.js”;
import { OrbitControls } from “three/examples/jsm/controls/OrbitControls.js”;
import { FBXLoader } from “three/examples/jsm/loaders/FBXLoader.js”;

知识点:

OrbitControls:通过Three.js的相机控件OrbitControls.js可以对Threejs的三维场景进行缩放、平移、旋转操作。
stats:两张图片分别表示当前场景的渲染帧率和显存占用情况;要使用该功能,必须包含如下源文件:stats.js或stats.min.js;
用法如下:

    stats = new Stats();
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.top = '0px';
    document.body.appendChild(_stats.domElement);

在渲染函数中,需要添加如下代码:
stats.update();
循环渲染代码如下:

function Animate()
{
    requestAnimationFrame(Animate);
    Render();
}

function Render()
{
    stats.update();
    render.render(scene,camera);
}

在这里插入图片描述在这里插入图片描述

材料(Materials)
Threejs提供了几种比较有代表性的材质,常用的有漫反射、镜面反射两种材质,还可以引入外部图片,贴到物体表面,称为纹理贴图。

(1).MeshBaseMaterial(网格基础材质)是一种非常简单的材质,这种材质不会考虑光照的影响。使用这种材质网格备渲染成简单的平面多边形,并且可以显示几何体的线框。
(2).MeshDepthMaterial(网格深度材质)使用该材质的物体的外观不是由某个材质属性决定的,而是由物体到相机的距离决定的,离相机越近越亮,离相机越远越暗。该材质的属性很少,没有设置物体颜色的属性。如果想改变物体的颜色,就需要创建多材质的物体。
(3).MeshNormalMaterial(网格法向材质)通过法向量来映射RGB颜色。每个法向量不同的面都会赋予不同的颜色。
(4).MeshFaceMaterial(网格面材质)可以为几何体每一个面指定不同的材质。比如一个立方体有六个面你可以为每个面指定一个材质。
(5).MeshLambertMaterial(网格朗伯材质)用于创建看上去暗淡的、不光亮的表面,可以对光源产生阴影的效果。
(6).MeshPhongMaterial(网格phong式材质)用于创建光亮表面的材质。可以产生阴影的效果。
(7).ShaderMaterial(着色器材质)该材质是最复杂的一种材质,可以使用自己定制的着色器。

光照(Lights)
常见的Loader:

3.创建场景、照相机、以及灯光

      container = document.createElement("div");
      height = document.getElementsByClassName("main-bim")[0].clientHeight;
      document.getElementById("threeView").appendChild(container);
      camera = new THREE.PerspectiveCamera(
        45,
        window.innerWidth / height,
        1,
        20000
      );
      camera.position.set(1000, 800, 0);
      scene = new THREE.Scene();
      scene.background = new THREE.Color(0x151c29);
      light = new THREE.HemisphereLight(0xffffff, 0x151c29);
      light.position.set(0, 200, 0);
      scene.add(light);
      light = new THREE.DirectionalLight(0x151c29);
      light.position.set(0, 200, 100);
      scene.add(light);
      renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, 710);
      renderer.shadowMap.enabled = true;
      container.appendChild(renderer.domElement);
      controls = new OrbitControls(camera, renderer.domElement);
      controls.target.set(80, 0, 0);
      controls.update();
      stats = new Stats();
      stats.dom.style.display = "none";
      container.appendChild(stats.dom);

4.加载FBX格式模型

 
      loader.load("fbx/喷涂机器人换电池分解.fbx", function(object) {
        actions = [];
        object.scale.set(2, 2, 2);
        object.position.set(290, 0, 430);
        object.name = "充电站机器人换电池";
        object.visible = false;
        mixer = new THREE.AnimationMixer(object);
        object.animations.map(function(item, index) {
          let obj = mixer.clipAction(object.animations[index]);
          obj.setLoop(0, 0);
          obj.setDuration(7);
          obj.clampWhenFinished = true;
          actions.push(obj);
        });
        scene.add(object);
      });
FBX动画执行
 index里面含有多个动画的每一个索引值
 actions[index].stop();//暂停动画
 actions[index].reset();//重置动画为初始状态
 actions[index].play();//执行动画
加载JSON文件
 现在的JSON格式有两个类型:
 一个是Geometry类型,需要JSONLoader加载;
 一个是Object类型,需要ObjectLoader加载。 

加载json格式数据

var js_loader = new THREE.JSONLoader(manager);
js_loader.load('./models/hmj/frame001.json', function(geometry, materials) {
    var material = new THREE.MultiMaterial(materials);    // 多个纹理
    var mesh = new THREE.Mesh(geometry, material);
    mesh.scale.multiplyScalar(.06);
    scene.add(mesh);
}, onProgress, onError);
var js_loader = new THREE.JSONLoader(manager);

json格式动画
var js_loader = new THREE.JSONLoader(manager);
js_loader.load('./models/body/climb.js', function(geometry, materials) {
    for(var i = 0; i < materials.length; i++) {
        materials[i].skinning = true;
    }
    var material = new THREE.MultiMaterial(materials);
    var mesh = new THREE.SkinnedMesh(geometry, material);    // 划重点啊!!!
    var mixer = new THREE.AnimationMixer(mesh);
    mixer.clipAction(geometry.animations[0]).play();
    mixers.push(mixer);
    mesh.scale.multiplyScalar(.05);
    mesh.lookAt(new THREE.Vector3(0, 0, 0));
    scene.add(mesh);
}, onProgress, onError);
加载object格式数据
var object_loader = new THREE.ObjectLoader(manager);
object_loader.load('./models/teapot-claraio.json', function(object) {
    object.scale.multiplyScalar(5);
    scene.add(object);
});

下面给出两种数据类型的区别:

Geometry类型
在这里插入图片描述
Object类型
在这里插入图片描述

纹理加载

obj格式文件不支持动画数据存储,只用于静态模型。
首先需要引入OBJLoader.js插件,如果纹理贴图是tga或dds格式的,
则还需要另外引入TGALoader.js或DDSLoader.js(纹理贴图问题同样适用于其他模型格式)。

var obj_loader = new THREE.OBJLoader(manager);
obj_loader.setPath('./models/mooncake/');    // 设置文件路径
var tga_loader = new THREE.TGALoader();
var material = new THREE.MeshPhongMaterial({
    map: tga_loader.load('./models/mooncake/Diffuse.tga'),设置颜色纹理贴图
    normalMap: tga_loader.load('./models/mooncake/Normal.tga'),
    specularMap: tga_loader.load('./models/mooncake/S.tga'),
    bumpMap: tga_loader.load('./models/mooncake/Bump.tga')
});   

存在多个纹理材质,具体参数Phong网孔材料(MeshPhongMaterial)

obj_loader.load('mooncake.obj', function(group) {
	    var geometry = group.children[0].geometry;
	    geometry.attributes.uv2 = geometry.attributes.uv;
	    geometry.center();
	    var mesh = new THREE.Mesh(geometry, material);
	    mesh.scale.multiplyScalar(.1);
	    scene.add(mesh);
	}, onProgress, onError);
obj+mtl(obj静态模型 - 外部载入纹理)
需要额外引用MTLLoader.js文件
var mtl_loader = new THREE.MTLLoader();
mtl_loader.setPath('./models/mooncake/');
mtl_loader.load('mooncake.mtl', function(materials) {
    materials.preload();
    obj_loader.setMaterials(materials);
    obj_loader.load('mooncake.obj', function(object) {
        object.scale.multiplyScalar(.1);
        scene.add(object);
    }, onProgress, onError);
});
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值