threeJs 封装DRACOLoader加载

article/2025/10/8 22:23:41

项目使用到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"><divid="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文件的秒加载实现


http://chatgpt.dhexx.cn/article/SFNedHuZ.shtml

相关文章

jsjsjsjs

length 用来获取字符串的长度 split(’ 分隔符’)用来将字符串拆分成数组 substring(需要截取的第一个字符的索引[,结束的索引号]) startsWith检测是否以某字符开头 endsWith检测是否以某字符结尾 函数 全局作用域&#xff1a;声明在全局的变量或者不使用var声明的变量在整个…

Three.js--》Gui.js库的使用讲解

目录 Gui.js库基本使用 使用three自带gui库实现基本操作 gui库实现下拉菜单和单选框 gui库分组方法实现 使用dat.gui第三方库 Gui.js库基本使用 gui.js说白了就是一个前端js库&#xff0c;对HTML、CSS和JavaScript进行了封装&#xff0c;学习开发3d技术时借助该库可以快速…

JSM的topic和queue的区别

在JMS&#xff08;Java消息服务&#xff09;中&#xff0c;Topic实现publish和subscribe语义。一条消息被publish时&#xff0c;它将发到所有感兴趣的订阅者&#xff0c;所以零到多个 subscriber&#xff08;电脑词汇中解释为“用户“&#xff09;将接收到消息的一个拷贝。但是…

小程序版 Three.js 框架下载及目录配置

1.库文件说明 由于微信官方提供的threejs适配库已经很久没有更新&#xff0c;而且开发者普遍反映使用起来很难用。 我这里分享的是独立的库文件&#xff0c;不需要npm安装&#xff0c;下载后将库文件放到项目中即可使用。 2.下载后的压缩包文件 3.解压后的文件夹结构 4.文件…

webpack使用Ammo.js - 在react中使用Ammo.js

真实麻烦啊 [我的项目仓库 Next.js项目 仅供参考](https://gitee.com/honbingitee/three-template-next.js/tree/feature%2Fphysics/)本文展示使用ammo.wasm.js 结合ammo.wasm.wasm的wasm版本使用方法1. 配置webpack2. 导出Ammo 修改ammo.wasm.js文件3. 删除语句 通过查找 this…

Vue里面使用threeJS 的 OrbitControls报错问题

vue使用 OrbitControls 首先需要按需引入 1、执行 npm install three --save-dev npm install three --save-dev 2 按需引入 import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls.js; 3 使用鼠标控制器 /*** 创建渲染…

JSM 2019 | 数据驱动在滴滴,详解智能出行时代的统计思维

桔妹导读&#xff1a;当地时间7月27日至8月1日&#xff0c;统计学领域顶级学术会议 JSM&#xff08;Joint Statistical Meetings&#xff09;在美国丹佛成功举行。丹佛是美国科罗拉多州的首府和最大城市&#xff0c;紧靠景色秀丽的落基山&#xff0c;气候宜人。平均海拔1610米&…

JM

第3章 JMX-MBean的HelloWorld实例 3.1 前言 Boss Connecter这个项目用到的技术还真够多的&#xff0c;这一章是要用到的JMX技术。什么是JMX&#xff1f;在一篇网文中是这样说的&#xff1a;“JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套…

Three.js--》实现3d圣诞贺卡展示模型

目录 项目搭建 初始化three.js基础代码 加载环境模型 设置环境纹理 添加水面并设置阴影效果 实现幽灵小球的运动 实现相机切换和文字切屏 实现漫天星星和爱心样式 今天简单实现一个three.js的小Demo&#xff0c;加强自己对three知识的掌握与学习&#xff0c;只有在项目…

Three.js 点击模型,高亮发光模型外轮廓

最近在开发一个功能&#xff0c;在三维场景里有很多模型&#xff0c;需要点击模型&#xff0c;高亮对应的模型&#xff0c;代表选中了该模型。做起来还是稍微麻烦一些的。 具体效果 实现流程 主要的流程还是&#xff0c; Created with Raphal 2.3.0 开始 获取鼠标点 射线碰撞…

Three.js--》实现3d汽车模型展览搭建

目录 项目搭建 初始化three.js基础代码 添加汽车模型展示 动态修改汽车模型 今天简单实现一个three.js的小Demo&#xff0c;加强自己对three知识的掌握与学习&#xff0c;只有在项目中才能灵活将所学知识运用起来&#xff0c;话不多说直接开始。 项目搭建 本案例还是借助…

vue3中使用three.js

现在vue3的项目中&#xff0c;大部分是vitevue3typescriptpinia的技术栈 vue3项目中安装three.js pnpm i types/three three 注意&#xff1a;在package.json中查看他们的版本&#xff0c;如果版本不一致的话&#xff0c;可能导致ts不能识别three这个模块 导入three模块 impor…

three.js学习笔记(十九)——后期处理

介绍 后期处理是指在最终图像&#xff08;渲染&#xff09;上添加效果。人们大多在电影制作中使用这种技术&#xff0c;但我们也可以在WebGL中使用。 后期处理可以是略微改善图像或者产生巨大影响效果。 下面链接是Three.js官方文档中一些关于后期处理的示例&#xff1a; http…

JMM--

数据同步的八大原子操作 1.lock 作用于主内存中的变量&#xff0c;把一个变量标记为一条线程的独占状态。 2.unlock 作用于主内存中的变量&#xff0c;把一个处于锁定状态的变量释放出来&#xff0c;释放后的变量才能被其它线程锁定。 3.read 作用于主内存中的变量&#xff0c…

Three.js--》实现3d小岛模型搭建

目录 项目搭建 初始化three.js基础代码 设置环境背景 设置水面样式 添加天空小岛 今天简单实现一个three.js的小Demo&#xff0c;加强自己对three知识的掌握与学习&#xff0c;只有在项目中才能灵活将所学知识运用起来&#xff0c;话不多说直接开始。 项目搭建 本案例还…

JMS简介

jms即Java消息服务&#xff08;Java Message Service&#xff09;应用程序接口是一个Java平台中关于面向消息中间件&#xff08;MOM&#xff09;的API&#xff0c;用于在两个应用程序之间&#xff0c;或分布式系统中发送消息&#xff0c;进行异步通信。Java消息服务是一个与具体…

java jsm_JSM 基础

JMS即Java消息服务(Java Message Service)应用程序接口&#xff0c;是一个Java平台中关于面向消息中间件(MOM)的API&#xff0c;用于在两个应用程序之间&#xff0c;或分布式系统中发送消息&#xff0c;进行异步通信。Java消息服务是一个与具体平台无关的API&#xff0c;绝大多…

JSM

消息中间件 消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流&#xff0c;并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型&#xff0c;它可以在分布式环境下扩展进程间的通信。对于消息中间件&#xff0c;常见的角色大致也就有Producer&am…

【HLL】使用 HyperLogLog 去重案例

1.概述 HyperLogLog一个常用的场景就是统计网站的UV。 ##基数 简单来说,基数(cardinality,也译作势),是指一个集合(这里的集合允许存在重复元素)中不同元素的个数。例如看下面的集合: {1,2,3,4,5,2,3,9,7} 这个集合有9个元素,但是2和3各出现了两次,因此不重复的元素…

5redis-----------redis高级--GEO-查询附近的人、基数统计算法HLL 、布隆过滤器、缓存雪崩穿透击穿-------全栈式开发44

redis高级 一、GEO查询附近的人二、基数统计算法-HyperLogLog三、布隆过滤器四、缓存雪崩&缓存穿透&#xff08;一&#xff09;缓存雪崩&#xff08;二&#xff09;缓存穿透&#xff08;三&#xff09;缓存击穿 一、GEO查询附近的人 引入 我们所处的任何位置都可以用经纬…