当前位置: 首页 > news >正文

Threejs中导入GLTF模型克隆后合并

        很多场景中会需要同一个模型很多次,但是如果多次加载同一个模型会占用很高的带宽,导致加载很慢,因此就需要使用clone,也就是加载一个模型后,其他需要使用的地方使用clone的方式复制出多个同样的模型,再改变复制出来的模型位置,达到一次加载,多次使用。但另一个情况是克隆的模型是新的模型,在threejs的场景中是一个完整独立的,具有一个正常模型所有的属性,很大,加载和渲染需要花费很多的时间,那么就又需要对克隆出的模型进行合并,成为一个整体的模型放到threejs的场景中。

        首先我们需要搭建一个threejs的场景,包括相机,灯光,渲染器等,这里为了方便看合并后的效果,再添加上State性能监视器。其他的场景搭建之前章节中都已存在这里就不贴代码了。性能监视器的代码如下

import Stats from 'three/addons/libs/stats.module.js';this.stats = new Stats();
document.body.appendChild(this.stats.domElement);

然后加载一个模型,我这里使用一个料箱模型作为演示的模型。

    initModel(){const loader = new GLTFLoader()loader.load("/static/models/box.glb", (gltf) => {this.scene.add(gltf.scene)})},

然后开始clone料箱。先clone1000个,并修改每个料箱的位置,此时发现threejs渲染已经非常吃力,FPS已经掉帧到12了。

initModel(){const loader = new GLTFLoader()loader.load("/static/models/box.glb", (gltf) => {let originaMesh = gltf.scene.children[0];for (let i = 0; i < 100; i++) {for (let j = 0; j < 10; j++) {for (let k = 0; k < 10; k++) {let mesh = originaMesh.clone()mesh.position.set(i*6,j*6,k*10);this.scene.add(mesh)}}}})},

然后我们开始模型合并,模型合并其实就是将每个模型的geometry克隆出来,放到一个集合中,最终把这个集合渲染为一个整体的大模型。

initModel(){const loader = new GLTFLoader()loader.load("/static/models/box.glb", (gltf) => {this.scene.add(gltf.scene)let meshArr = []let originaMesh = gltf.scene.children[0];for (let i = 0; i < 100; i++) {for (let j = 0; j < 10; j++) {for (let k = 0; k < 10; k++) {let mesh = originaMesh.clone()mesh.position.set(i*6,j*6,k*10);mesh.updateMatrixWorld(true);const geometry = mesh.geometry.clone();geometry.applyMatrix4(mesh.matrixWorld);meshArr.push(geometry)}}}const bayGeometry = mergeGeometries(meshArr,true);const material = new THREE.MeshStandardMaterial({ color: '#0000FF' });const totalMesh = new THREE.Mesh(bayGeometry, material);totalMesh.name="大模型"this.scene.add(totalMesh);})},

最终通过模型合并,1000个料箱同时展示,FPS又回到了60,因为对于threejs来讲,只有一个模型了,渲染也是一次成型。

如果有疑问或者需要源码可以给我留言。

http://www.lryc.cn/news/411091.html

相关文章:

  • 今日arXiv最热大模型论文:北京大学最新综述:视觉大模型中的漏洞与攻防对抗
  • 为什么IDEA中使用@Autowired会被警告
  • uniapp使用cover-view,使用@click无效
  • Postman 接口测试工具简易使用指南
  • Move生态:从Aptos和Sui到Starcoin的崛起
  • MacOS DockerDesktop配置文件daemon.json的位置
  • 从光速常数的可变性看宇宙大爆炸的本质
  • 敢不敢跟我一起搭建一个Agent!不写一行代码,10分钟搞出你的智能体!纯配置也能真正掌握AI最有潜力的技术?AI圈内人必备技能
  • vue3和vite双向加持,uni-app性能爆表,众绑是否有计划前端升级到vue3!
  • 2024年最强网络安全学习路线,详细到直接上清华的教材!
  • 人脸识别又进化:扫一下 我就知道你得了啥病
  • yolov8标注细胞、识别边缘、计算面积、灰度值计算
  • WEB前端11-Vue2基础01(项目构建/目录解析/基础案例)
  • QT--线程
  • 通过进程协作显示图像-C#
  • LangChain链与记忆处理[10]:四种基础内置链、四种文档处理链,以及链的自定义和五种运行方式,让你的大模型更加智能
  • 京东发行稳定币的背后
  • CF1995C Squaring 题解
  • 动态规划之路径问题
  • 如何优化你的TikTok短视频账号运营策略?
  • mysql的唯一索引和普通索引有什么区别
  • Scrapy框架在处理大规模数据抓取时有哪些优化技巧?
  • 私有化低代码平台的优势:赋能业务用户,重塑IT自主权
  • SAP BW系统表分享第一弹
  • 详解工厂模式与抽象工厂模式有什么区别?【图解+代码】
  • zeroice做json字符串转为struct,支持结构体嵌套
  • Linux笔记 --- 内存管理
  • 树莓派通过webRTC进行视频流传输到公网
  • 【数据结构与算法】循环队列
  • 为什么推荐使用@RequiredArgsConstructor代替@Autowired?