Three.js-硬要自学系列13 (加载gltf外部模型、加载大模型)

本章主要学习知识点

  • 学会在three.js中加载gltf模型
  • 掌握使用DRACO解压大模型

加载gltf模型

导入GLTF加载器

js 复制代码
  import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

加载模型

js 复制代码
const loader = new GLTFLoader(); 
loader.load('model/3D_stall_2-Oo3.glb', (gltf) => {
    scene.add(gltf.scene); // 把模型放进场景 
});

效果图

模型不显示,问题排查

  • 检查文件路径是否正确。
  • 确认添加了光源(没光看不见!)。
  • 调整相机位置,别让模型在视线外。

色彩不对

模型颜色如果不对,需要设置渲染器的颜色空间

js 复制代码
renderer.outputColorSpace = THREE.SRGBColorSpace;

加载大模型

大模型加载面临的问题

  • 文件太大:比如几百MB的模型,直接加载会长时间白屏。
  • 性能吃内存:模型细节多(如建筑模型有门窗、家具),可能让浏览器卡死。
  • 网络传输慢:用户网速差时,下载模型文件会很久。

解决方案以及技巧

1.预处理模型
  • 减面:用建模软件(如Blender)删除看不见的细节,比如建筑内部结构
  • 拆分模型:把大楼拆成「楼层」或「房间」,按需加载(用户走到哪层再加载哪层)
  • 压缩纹理 :高分辨率贴图缩小尺寸(比如从4096x4096降到1024x1024),或用压缩格式(如.basis
2.分块加载
  • 先骨架后细节:先加载低精度模型,再逐步加载高精度细节(类似游戏中的LOD技术)
  • 按区域加载:例如开放世界游戏,只加载用户视野范围内的区域。
3.性能优化
  • BufferGeometry:比普通几何体更省内存
  • 模型复用 :比如场景中有100棵树,只加载一次模型,其他用.clone()复制
  • 及时清理内存 :离开场景时用.dispose()删掉不用的模型
4.压缩和传输
  • Draco 压缩 :用 gltf-pipeline 工具压缩模型,文件体积减少70%以上(需搭配解码器)
  • JSZip 传输:把模型文件压缩成.zip,传输后浏览器解压(实测压缩率90%)
5.针对性解决
  • 模型卡顿:开启视锥剔除(自动隐藏视野外的物体)
  • 加载慢:用CDN加速模型文件传输,或启用浏览器缓存
  • 体积大 : 优先用 .glb(二进制格式,比 .gltf 更小)

讲了这么多概念,让我们来操作下, 下面将会用到Duck.glbcity.glb这两个模型,city.glb已经过压缩处理,使用的是gltf-pipeline这个工具进行压缩,虽然进过压缩,但这个模型仍有10M的大小,注意因为是基于draco进行编码压缩,所以项目里需要使用draco进行解码

导入解码器加载模型

js 复制代码
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';

const loader = new GLTFLoader(loadingManager);
const dracoLoader = new DRACOLoader(loadingManager);
// 设置解码器的路径
dracoLoader.setDecoderPath('draco/');
// 绑定解码器
loader.setDRACOLoader(dracoLoader);
// 载如模型
loader.load(
    'model/Duck.glb',
    (gltf) => {
      scene.add(gltf.scene)
    }
)
loader.load(
    'model/city.glb',
    (gltf) => {
      scene.add(gltf.scene)
    }
)

设置完毕后,打开浏览器你会发现,黑漆漆的一片

我们第一直觉就是没有光,于是上帝说要有光,我们就创造一个环境光

这里除了添加光以外,添加环境贴图同样可以实现这个缤纷的城市

js 复制代码
const rgbeLoader = new RGBELoader(loadingManager)
rgbeLoader.load(
    'texture/Alex_Hart-Nature_Lab_Bones_2k.hdr',
    (texture)=>{
      // 设置纹理的映射方式
      texture.mapping = THREE.EquirectangularReflectionMapping;
      // 设置环境贴图
      scene.environment = texture;
    }
)

以上案例均可在案例中心查看体验

THREE 案例中心

相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大2 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师2 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学2 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端