码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • three.js初体验 如何将400M的3d模型压缩到3M


    一、背景

             客户发来了一个400M的3d模型文件,obj+mtl+png格式的,如下图:

      要求用h5展示出来,效果类似于博物馆文物的3D展示。

    二、初步实现思路

            据我有限的所知,目前的3d js库有Three.js 和 Babylon.js。之前听说过Three.js,就打算用它实现,但看文档一下就懵了。因为我用的是vue开发,偶然搜到vue-3d-model这个组件,几行代码就能实现3d展示,核心代码如下:

    1. :backgroundAlpha="0"
    2. @on-load="onLoad"
    3. src="static/models/obj/male02/male02.obj"
    4. mtl="static/models/obj/male02/male02.mtl"
    5. >

            在本地这个项目跑起来已经比较慢,因为要加载400M文件,慢很正常。于是开始想办法优化。试了用Blender、Polygon Cruncher做减面,效果不理想。期间走了很多弯路,装了很多软件不再赘述。下面直接给出优化步骤。

    三、优化步骤

    1.压缩PNG

            这一步非常关键,且容易忽略,但这一步压缩比例最高:原图是8192*8192的60M大的PNG,先把分辨率降为400*400,再用tinypng网站或软件降低质量进一步压缩。图片锐减为100KB。

            注意:这一步要多看效果(可使用win10自带的3D查看器),在清晰度和文件大小间反复衡量、取舍。尤其注意带文字的部分是否能看清。

    2.合并为gltf

            使用obj2gltf.js 将obj\mtl+png 合并为gltf。obj2gltf.js的安装比较繁琐,且中间要解决几个错误(主要是缺少fs-* 等js库),网上有教程,自行百度。转换命令如下:        

    node bin\obj2gltf.js -i TM00001.obj -o tm.gltf

            推荐使用Blender软件,转换比较方便:导入obj,然后导出gltf嵌入式即可。这时候tm.gltf文件有14M大小,打开会看到内容是json格式,内嵌了base64格式的图片。

            另外:Blender也可以导出分离的gltf。这是分成gltf文件、bin文件、若干贴图。

    3.转换glb

            gltf在用于3d展示时,图片部分要做base64解码,也需要消耗资源。因此可以使用glb格式,这种格式用二进制形式存储json和图像,进一步压缩文件大小,且在展示时能省略图像的base64解码 。

            可以使用gltf-pipeline转换:                

    gltf-pipeline -i tm.gltf -o tm.glb

            如果没有gltf-pipeline ,需要事先安装:        

    npm install -g gltf-pipeline --registry=https://registry.npmmirror.com

            也可以用Blender软件转换,且可以直接从obj转换为glb:导入obj,导出glTF二进制(.glb)即可。但是切记不要选择压缩。

            转换为glb后大小为10M,大小变化不大。

    4.Draco压缩glb

             10M大小的文件,加载时间也很长。 有没有进一步压缩的空间?有,使用压缩算法。Blender软件在导出glb文件时,可以选择压缩(红色箭头),如下图:

    此时采用的Draco算法进行压缩。压缩后文件可以降为2M,但这时vue-3d-model已不支持,需要修改一下组件,加入Draco的支持。但最终效果并不理想,10s左右才能加载完,比未压缩的glb文件性能相当,原因是Draco算法解码存在瓶颈。且有明显的失真,能看到模型出现了空白的缝隙。

    5.EXT_meshopt_compression压缩glb

            使用EXT_meshopt_compression算法也可以压缩glb,需要事先安装gltfpack

    npm install -g gltfpack --registry=https://registry.npmmirror.com

     压缩命令:

    gltfpack -i tm.glb -o tm-me.glb -cc

    此时文件缩小为不足3M,虽然比Draco算法压缩后的文件略大,但是由于解码快,2s内就能加载完。这时vue-3d-model也不支持,需要简单改造,示意代码如下:

    1. import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
    2. import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js'
    3. const loader = new GLTFLoader();
    4. loader.setMeshoptDecoder(MeshoptDecoder);

    需要注意的是:three.js版本要升级,大于r122(0.122?我用的是0.143.0)。

    四、总结

    我对obj+mtl+png格式的3d模型文件压缩步骤如下:

    1.压缩png:降低分辨率;再使用tinypng降低质量。

    2.使用Blender软件转换glb文件。(不要压缩)

    3.使用gltfpack采用-cc选项压缩

    五、改进思路

    1.使用Blender修改器--精简,去减面。注意:会失真。

    2.使用oss+cdn存储glb文件。这是很有必要的,因为模型文件相对于js、css很大,不存在oss上,应用服务器带宽很容易被打爆。

    3.感觉分离的gltf文件,也有优势,因为可以多个文件同时加载。但不确定能否压缩。没有尝试。

    4.因为gltf文件中最大的部分还是图片,看到有的实现:将图片分为缩略的小图和高清大图,默认加载缩略图,减少用户等待时间。待大图加载完毕后,再替换成大图。这种应该可以通过简单修改GLTFLoader就可以实现。

    5.使用OSGB格式:猜测类似于地图瓦片,逐级加载。初始时只需要加载小图,放大后可以加载大图(也是一部分)。这种方式对要求精细细节的人员比较友好,且能解决一次性加载所有资源的性能瓶颈。

    参考:https://copyfuture.com/blogs-details/20210816052547375s引言 最近做T級互動,需要使用到3D模型。相信大家和我一樣,在開始著手的時候,一定會有這麼些問題: 1.如何選擇3D模型的導出格式 2.如何對模型文件進行優化 3.在大流量的項目中兼容性怎麼樣 讓我們通過這篇文章,進行細致的探索、調研與沉澱。 一、什麼是 glTF 文件 glTF (https://github.com/KhronosGroup/glTF Tutorials/blob/master/gltfTutorial/gltfTutorial_002_BasicGltfStructure.md) 全稱 Graphics Language Transmission Format ,是三維場景和模型的標准文件格式。 glTF 核心是 JSON 文件,描述了 3D 場景的整個內容。它由場景結構本身的描述組成,其由定義場景圖的節點的層次提供。 場景中出現的 3D 對象是使用連接到節點的 meshes(網格)定義的。Materials(材料)定義對象的外觀。Animations(動畫)描述 3D 對象如何隨著時間的推移轉換 3D 對象,並且 Skins(蒙皮)定義了對物體的幾何形狀的方式基於骨架姿勢變形。Cahttps://copyfuture.com/blogs-details/20210816052547375s

    【网格压缩测评】MeshQuan、MeshOpt、Draco - 知乎

  • 相关阅读:
    Qt编写物联网管理平台43-告警短信转发
    一篇文章让你入门【MySQL】
    2000-2021年上市公司全要素生产率数据(LP法)(含原始数据、计算代码、计算结果)
    volatile关键字的可见性_java培训
    关于CASIO系列可编程计算器在公路施工测量中的应用
    SAS学习8、9(方差分析、anova过程、相关分析和回归分析、corr过程、reg过程、多元线性回归、stepwise)
    2024年孝感市建筑类中级职称申报资料私企VS国企
    API商品接口对接使用:从理论到实践
    golang中实现一个异步延时程序
    C语言连续换行输入多组数据怎么解决?
  • 原文地址:https://blog.csdn.net/dzhq1984/article/details/126182451
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号