vue中使用threejs注意事项

最近在vue项目中使用threejs一下都是踩过的雷点

卡顿问题

在vue中three.js的相机,场景,渲染器,控制器,都不能放在data中,否则会导致项目运行使用出来后很卡

 //将以上的东西放在mounted中创建,前面加上this.也是全局变量
 mounted() {
     this.scene = null
    this.renderer = null
    this.camera = null
    this.controls = null
    this.init()
  },
  //后续还要在beforeDestory中进行销毁
  beforeDestroy() {
    this.scene = null
    this.renderer = null
    this.camera = null
    this.controls = null
  }

threebsp

通过npm 安装threebsp库后发现每次运行都会报错,尝试自己把threebsp的代码复制进来后导出,也是一样的报错.后来通过这个安装旧版本的方法解决.

纹理贴图

在使用TextureLoader纹理贴图的方法时不能直接.load(url),这样无法url路径的图片渲染

//使用require方法请求到路径.在放到.load方法里
const Texturing = require('../../../public/static/images/floor.jpg')
    const loader = new THREE.TextureLoader()
    loader.load(Texturing, (texture) => {
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping
        texture.repeat.set(10, 10);
        const floorGeometry = new THREE.BoxGeometry(floorWidth,floorHeight,floorDepth)
        const floorMaterial = new THREE.MeshBasicMaterial({
            map: texture,
        });
        const floor = new THREE.Mesh(floorGeometry, floorMaterial)
        floor.rotation.x = -Math.PI / 2
        floor.name = "地面";
        scene.add(floor);
    })

但后续创建天空盒需要把图片路径以数组的方式放进去,无法解决,导致天空盒内部无法渲染图片,尚未解决…
天空盒最终使用 scene.background = skyboxCubeMap方式放入scene场景,但是效果不佳

相机视角问题

当controls控制器设置了controls.target时,camera.lookAt方法将失效,在render中添加updata中更新相机视角,不使用会出现刚进项目相机视角以(0,0,0)为中心,使用鼠标控住后会刷新成以control中设置的点为中心控制.

    render() {

      this.controls.update()  //使用控制器设置旋转后更新,设置控制器后camera不能设置lookat,在这里uodate更新相机
    },

鼠标点击事件

要将二维坐标转换为三位坐标,我也不太懂,这里说一下canvas不是全屏时的计算公式

 let x = ((event.clientX - this.element.getBoundingClientRect().left) / this.element.offsetWidth) * 2 - 1;
      let y = -((event.clientY - this.element.getBoundingClientRect().top) / this.element.offsetHeight) * 2 + 1;

完整点击事件代码

onMouseClick(event) {
//this.element 是当前div的id 
// this.element = document.getElementById('container') 通过这句代码获取
      let x = ((event.clientX - this.element.getBoundingClientRect().left) / this.element.offsetWidth) * 2 - 1;
      let y = -((event.clientY - this.element.getBoundingClientRect().top) / this.element.offsetHeight) * 2 + 1;
      // 标准设备坐标转为世界坐标
      let standardVector = new THREE.Vector3(x, y, 1);
      let worldVector = standardVector.unproject(this.camera);

      // 射线投射方向单位向量(worldVector坐标减相机位置坐标)
      let ray = worldVector.sub(this.camera.position).normalize();

      // 创建射线投射器对象
      let rayCaster = new THREE.Raycaster(this.camera.position, ray);
      // 返回射线选中的对象数组(第二个参数默认值是false,意为是否遍历图形内部的所有子图形)
      let intersects = rayCaster.intersectObjects(this.scene.children, true);
      if (intersects.length > 0 && intersects[0].object.name == '货物1') {
        // 射线拾取的首个对象
        let currObj = intersects[0];
        console.log(currObj);
        console.log(currObj.object.name)
        alert("干巴爹")
        }


 this.element.addEventListener('click', this.onMouseClick, false)//通过监听事件触发

点击事件可以通过object.name来筛选是否需要点击的物体

立体文字问题

three.js的立体文字库是json格式的,但是不支持中文,我们需要先在网上下载TTF格式的,然后转化成json格式转换格式链接,
但是中文转换成json格式就会有一个很大问题,文件会变得巨大,基本都在几十兆,这要用到前端项目显然是不可能的,有一种方法是,先对ttf格式的文件进行文字删减,百度可以可以找到工具,保留自己需要的几个汉字,然后在进行json格式的转换,当然数字和英文字母,符号基本需要保留.

静态文件路径问题

上文所说的json文字文件,以及贴图文件都需要放在vue项目中public文件夹中,静态文件都需要方法public中.

模型共用问题

由于使用多个重复模型的时候使用clone方法,导致所有的模型都共用一个material,就会导致添加点击事件触发修改material时所有的模型都会被修改

//在clone模型后重新赋予material,这样每一个模型的material就是独自的材质,不会造成互相干扰
 good2.material=new THREE.MeshLambertMaterial( {color: "#ddffdd"});

放上我的vue项目github地址,有需要的可以看一下,正在逐步完善

未完待续

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值