项目需求:要将3d模型显示在网页上 并实现时时旋转和鼠标悬停功能.给我的3d模型是60M的obj文件
threejs加载obj模型比较简单但加载时间很长 毕竟60m的文件网络传输需要很长时间
obj模型太大 必须想办法压缩 google的第一个链接就有解决办法
第一步 将obj转换成gltf文件
通过obj2gltf工具 可以吧obj转换成gltf文件 大小大约为20M 但是还是很大 因为在网络不好的环境下下载20m文件还是需要很长时间
threejs 显示20m的gltf文件为1s
第二步 使用draco压缩gltf文件
gltf-pipeline工具可以压缩gltf文件 大小大约2m 但是又有新的问题 threejs在加载的时候需要解压缩 也就是说显示2m的文件需要5s的时间 而且每次刷新都需要重新解压缩 每一次刷新都需要5s的时间显示3d模型.
下图分别是 gltf文件 obj文件 和压缩的gltf文件的大小
那么现在有两种方案
方案一
使用20m的gltf文件加浏览器缓存 那么只有在第一次的时候需要加载20m的文件 以后每次刷新都只需要1s的时间显示模型
方案二
使用压缩后的gltf文件 第一次只需要加载2m的文件 但每次刷新都需要5s的时间显示模型
我们仔细考虑一下这两个方案
方案一 优点 每次刷新加载的时间只需要1s
方案二 优点 只需要加载2m的gltf文件
那么怎么把这两个方案的优点结合起来 实现 只需要加载2m的文件 又可以让模型的显示只需要1s
自然而然就可以想到
方案三
加载2m的文件 在第一次解压后 将解压的数据存起来 然后每一次刷新 直接取存好的数据这样就可以 实现 即加载2m的文件又可以让模型的显示只需要1s
那么怎样实现数据的存储 因为 localstorage最大存储为5m 并不能存大量的数据 所以只能使用indexdb 但使用indexdb的时候是又有新的问题
在第一次解压后 将数据存储起来需要3s的时间 也就是说 第一次显示模型 需要8s(5s的解压缩+3s的存储)
虽然就第一次慢一些 后面每一次刷新都只需要1s的时间
但是还是不能容忍 要客户等待8s 的时间
那么怎样实现 第一次显示也很快 那么自然而然想到 当客户还没进入到模型显示页面的时候 就已经开始加载这些数据 能不能像java那样使用多线程 换句话说 在用户登录的时候另一个线程就已经开始加载模型 解压缩 存储数据 ,然后第一次显示模型的时候就直接从数据库取数据
通过了解发现 webworker就可以实现那么就有了方案四
方案四
在登录页面时利用webworker加载模型 解压缩 存储数据 当用户进入到模型页面时从数据库取数据直接加载 实现第一次秒加载和后续的秒加载
demo地址
https://github.com/kaikai55/loadbigobj/tree/master
上面是研究过程 但是在实际应用中 由于我们自己有3d结构师 通过把模型精简 obj文件只有36m 压缩后的gltf只有2m 考虑到浏览器支持和代码复杂度 最终使用方案三