threeJs 封装DRACOLoader加载

2023-05-16

项目使用到3D模型加载渲染,故初学习了解之,

简单封装 代码如下

import * as THREE from "three";
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";
import {ShaderPass} from "three/examples/jsm/postprocessing/ShaderPass";
import {FXAAShader} from "three/examples/jsm/shaders/FXAAShader";
import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader";
import {DRACOLoader} from "three/examples/jsm/loaders/DRACOLoader";
import {EffectComposer} from "three/examples/jsm/postprocessing/EffectComposer";
import {RenderPass} from "three/examples/jsm/postprocessing/RenderPass";
import {OutlinePass} from "three/examples/jsm/postprocessing/OutlinePass";

class ThreeJsLoder {
  constructor(ref) {
    this.webglRef = ref;
    this.canvasSetting = {width: 960, height: 500}
    this.camera = new THREE.PerspectiveCamera(50, this.canvasSetting.width /   	this.canvasSetting.height, 1, 2000);
    this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
    this.HemisphereLight = new THREE.HemisphereLight(0xffffff, 0xaaaaaa, 1);
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    this.scene = new THREE.Scene();
    this.devices = [];
    this.rayCaster = new THREE.Raycaster();
    this.effectFXAA = new ShaderPass(FXAAShader);
    this.gltfLoader = new GLTFLoader();
    this.dracoLoader = new DRACOLoader();
    this.dracoLoader.setDecoderPath("/draco/");
    this.dracoLoader.setDecoderConfig({type: 'js'});
    this.gltfLoader.setDRACOLoader(this.dracoLoader);
    this.composer = null;
  }

  /**
   * 加载模型
   * @param link 模型地址
   * @param eleId domId
   * @param onSuccess 成功回调
   * @param onProgress 加载过程回调
   * @param onError 失败回调
   */
  loadModel(link, eleId, onSuccess, onProgress, onError) {
    this.clear();
    this.gltfLoader.load(link, (gltf) => {
      gltf.scene.position.set(0, 20, 0);
      gltf.scene.scale.set(2.2, 2.2, 2.2);
      this.camera.position.set(10, 80, -80);
      
      this.scene.add(gltf.scene)   
      this.scene.add(this.HemisphereLight);
      this.scene.add(this.camera);
      
      this.renderer.setClearColor(new THREE.Color(0x000000));
      this.renderer.setSize(this.canvasSetting.width, this.canvasSetting.height);
      this.webglRef.appendChild(this.renderer.domElement);


      this.controls.addEventListener('change', () => {
        this.renderer.render(this.scene, this.camera)
      });
      this.controls.autoRotateSpeed = 1.5;
      this.controls.target.set(0, 0, 0);
      this.controls.update();
      this.renderer.render(this.scene, this.camera);
      gltf.scene.traverse((r) => {
        if (r instanceof THREE.Mesh) {
          this.devices.push(r);
        }
      });

      if (onSuccess) {
        onSuccess();
      }

    }, (xhr) => {
      if (onProgress) {
        let percentComplete = null;
        if (xhr.lengthComputable) {
          percentComplete = xhr.loaded / xhr.total * 100;
        }
        onProgress(xhr, percentComplete);
      }

    }, (e) => {
      if (onError) {
        onError(e);
      }
    });
  }


  /**
   * 获取点击的模型构件,创建选区效果,返回首个mesh对象
   * @param event
   * @param eleRef
   * @returns {boolean}
   */
  getChoose(event) {
    let x = (event.offsetX  / this.canvasSetting.width) * 2 - 1;
    let y = -(event.offsetY  / this.canvasSetting.height) * 2 + 1;
    this.rayCaster.setFromCamera(new THREE.Vector2(x, y), this.camera);
    let intersects = this.rayCaster.intersectObjects(this.devices);
    let mesh = false;
    if (intersects.length > 0) {
    //匹配首个目标对象
      mesh = intersects[0].object;     
      this.outlineObj(mesh)
    } else {
      this.renderer.render(this.scene, this.camera);
    }
    return mesh;
  }

  //给选中的构件模型 加个边框
  outlineObj(obj) {
    if (obj) {
      this.composer = new EffectComposer(this.renderer);
      const renderPass = new RenderPass(this.scene, this.camera);
      this.composer.addPass(renderPass);
      const outlinePass = new OutlinePass(
        new THREE.Vector2(this.canvasSetting.width, this.canvasSetting.height),
        this.scene,
        this.camera
      );
      outlinePass.selectedObjects = [obj];
      outlinePass.edgeStrength = 30.0;
      outlinePass.edgeGlow = 0;
      outlinePass.usePatternTexture = false;
      outlinePass.edgeThickness = 3.0;
      outlinePass.downSampleRatio = 1;
      outlinePass.pulsePeriod = 1;
      outlinePass.visibleEdgeColor.set(parseInt(0xff6347));
      outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0);

      outlinePass.clear = true;
      this.composer.addPass(outlinePass);

      // 自定义着色器通道
      this.effectFXAA.uniforms["resolution"].value.set(
        1 / window.innerWidth,
        1 / window.innerHeight
      );
      this.effectFXAA.renderToScreen = true;
      this.composer.addPass(this.effectFXAA);
      this.composer.render()
    } else {
      this.composer = null;
    }
  }

  clear() {
    this.devices.splice(0, this.devices.length);
    this.scene.clear();
    this.camera.clear();
    this.renderer.clear();
    this.controls.update();
    this.renderer.render(this.scene, this.camera)
    this.webglRef.innerHTML = " ";
  }

}


export {ThreeJsLoder}

#obj转gltf文件 
obj2gltf -i luyu.obj -o luyu.gltf
#压缩gltf文件
gltf-pipeline -i luyu.gltf -o out.gltf -d 

vue2.x 使用

1.node_modules文件下 找到three文件夹, 找到/examples/js/libs/draco/ 将draco整个文件夹复制到public路径下
2.threeJS中的渲染对象 不可用vue的数据方向绑定,会造成卡顿

<template>
  <div v-loading="!webglShow">
    <div
      id="webgl"
      ref="webgl"
      @click="clickEvent"
    ></div>
  </div>
</template>

<script>
import {ThreeJsLoder} from "@/utils/ModelConfig/ThreeJsLoder";
let threeJsLoder;


export default {
  props: ["modelForm"],
  name: "ModelConfig",
  data() {
    return {
      webglShow: false,
      mesh: {},
    }
  },
  mounted() {
    this.init({link:"压缩gltf的路径地址"});
  },
  methods: {
    init(item) {
      modelConfig = new ThreeJsLoder(this.$refs.webgl);
      modelConfig.loadModel(item.link,()=>{
        this.webglShow = true;
      })
    },
    clickEvent(event) {
      this.mesh = modelConfig.getChoose(event);
      if(this.mesh){
       console.log(this.mesh);
      }
    },



};
</script>
<style scoped>

</style>

效果如图,

在这里插入图片描述
参考
Threejs大型obj文件的秒加载实现

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

threeJs 封装DRACOLoader加载 的相关文章

随机推荐

  • cross_val_score的 scoring参数值解析

    一般我们在模型训练过程中 xff0c 会采用K折交叉验证的方法来验证模型的表现 xff0c 从而进行调参 xff0c 一般我们会用到 sklearn model selection 的 cross val score 方法来计算模型的得分
  • windows 10下 itunes 备份默认存储路径问题

    最近在研究iphone手机备份的问题 xff0c 在使用itunes给手机备份的时候 xff0c 发现C盘空间不够用了 xff0c 于是想把itunes的默认存储路径修改一下 xff0c 在网上查找资料了解了相关操作教程后 xff0c 发现
  • MAC查看与修改系统默认的shell

    查看系统当前默认使用的shell有如下几个方法 一 查看所有的shell cat etc shells 输出 List of acceptable shells for chpass 1 Ftpd will not allow users
  • windows下redis的配置文件(redis.windows.conf)

    redis的配置 Redis默认不是以守护进程的方式运行 xff0c 可以通过该配置项修改 xff0c 使用yes启用守护进程 daemonize yes 当Redis以守护进程方式运行时 xff0c Redis默认会把pid写入redis
  • UITabBarController

    1 UITabBarController的常用属性和方法 一般来说 xff0c 目前市面上的App很多都是由一个UITabBarController管理着4 xff5e 5个UINavigationController xff0c 然后每个
  • LJSpeech-1.1.tar.bz2 下载分享

    数据集 xff1a http data keithito com data speech LJSpeech 1 1 tar bz2 xff08 用迅雷下载很快 xff09 百度网盘地址 xff1a 链接 xff1a https pan ba
  • cookie存放位置(Win10)

    IE浏览器 xff1a APPDATA Microsoft Windows Cookies 目录中的xxx txt文件 xff08 IE浏览器分开存放的 xff09 火狐浏览器 xff1a APPDATA Mozilla Firefox P
  • C语言 将一个整数的二进制序列分别输出

    include lt stdio h gt int main int i j num char arr1 16 char arr2 16 printf 34 输入一个整数 xff1a 34 scanf 34 d 34 amp num for
  • openSSL中SSL_MODE_AUTO_RETRY使用引发的问题

    1 SSL MODE AUTO RETRY的作用 关于这个flag的作用 xff0c openSSL官方的解释如下所示 xff1a SSL MODE AUTO RETRY Never bother the application with
  • Github下载代码和运行

    本文介绍利用Git工具下载和运行GitHub代码 文章目录 一 Win下载安装Git二 运行python代码1 下载Github代码2 运行代码 一 Win下载安装Git 官网下载 xff1a https git scm com downl
  • 批量修改txt文件名,删除相同部分

    转载 xff1a https www cnblogs com cyh2009 p 10593776 html 1 在包括需要修改的txt文件夹中新建txt文件 xff0c 输入 xff1a 64 echo off span class to
  • 8086汇编指令笔记

    8086 8088汇编指令总结 一 数据传送指令 1 传送指令 xff1a MOV move 格式 xff1a mov dst src 具体用法 xff1a 1 CPU内部寄存器之间的数据传送 xff0c 如 xff1a mov ah al
  • CentOS(linux)循环登录(闪退)的一种可能的解决方法

    前言 最近开机之后通过远程ssh刷init 5进系统时发现 xff0c 我经常使用的账号输入账号密码后屏幕闪一下又回到登录界面 xff0c 也就是所谓的循环登录 xff0c 其他的账号登录都是正常的 xff0c 烦了我有一段时间了 xff0
  • 百度ECharts地图 地名位置坐标微调

    百度ECharts地图 地名位置坐标微调 百度Echarts出现地市名字不居中或者重叠 下载的地图json数据里坐标位置导致出现这种问题 下载的地图json数据里坐标位置导致出现这种问题 xff0c 修改json数据中的cp 属性存储的是经
  • Java中抽象类 abstract和interface的区别

    abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制 xff0c 正是由于这两种机制的存在 xff0c 才赋予了Java强大的面向对象能力 abstract class和interface之间在对
  • Java Vue uni-app 三端实现,滑动拼图验证码

    一步一步实现 图片滑动验证码 项目中要使用 图片滑动验证码 xff0c 顾了解之 需要以下几步来完成 xff1a 1 后端随机计算抠图的距离 xff0c 生成背景与拼图块的图片 xff0c 缓存 拼图块需 滑动的距离像素 2 前端加载背景图
  • DES与3DES 加解密实例(c++)

    DES与3DES 加解密实例 xff08 c 43 43 xff09 DES原理 xff1a DES算法是一种对称密码算法 xff0c 也是一种分组加密的算法 xff0c 以64位分组对数 据加密的 xff0c 其密钥长度为64位 xff0
  • java打印杨辉三角形

    前言 xff0c 打印杨辉三角形对于初级的程序员来说并不难 xff0c 主要掌握几个核心的知识点就行了 xff0c 其运用到二维数组 for循环 if条件语句等 杨辉三角形的特性如下 xff1a 它的两条斜边都是由数字1组成的 xff0c
  • Windows server2019安装docker

    安装Docker Desktop Microsoft Windows Docker安装 一 安装Docker二 配置Docker1 Docker停止所有容器 清理缓存 xff1a 2 拉取镜像 EMQX 为例 xff1a 1 获取EMQX镜
  • threeJs 封装DRACOLoader加载

    项目使用到3D模型加载渲染 xff0c 故初学习了解之 xff0c 简单封装 代码如下 span class token keyword import span span class token operator span span cla