当前位置:首页 > 科技  > 软件

基于 Three.js 的 3D 模型加载优化

来源: 责编: 时间:2024-07-19 08:01:57 267观看
导读一、前言近段时间,我们使用three.js完成了vivo拟我形象的开发工作,大家可以在vivo账号中拟制属于自己的3D形象,也可以保存作为自己的头像名片。
作为一个3D的项目,从用户打开页面到最终模型的渲染需要经过多个流程,加载的

pjK28资讯网——每日最新资讯28at.com

一、前言

近段时间,我们使用three.js完成了vivo拟我形象的开发工作,大家可以在vivo账号中拟制属于自己的3D形象,也可以保存作为自己的头像名片。pjK28资讯网——每日最新资讯28at.com


pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

作为一个3D的项目,从用户打开页面到最终模型的渲染需要经过多个流程,加载的时间也会比普通的H5项目要更长一些。然而过长的等待时间会造成大量的用户流失,这部分用户没有体验到具体的功能就退出了页面非常的遗憾,为了提升首屏加载的转化率,需要尽可能的降低loading的时间。这里就分享一些我们在模型加载优化方面的心得。pjK28资讯网——每日最新资讯28at.com

二、模型加载的优化思路

想对加载进行优化,首先需要了解Three.js加载模型时的工作流程,并分析出其中耗时的部分进行针对性的处理。pjK28资讯网——每日最新资讯28at.com

在Three.js中,模型从加载到渲染需要经过模型下载、序列化模型、网格解析、写入缓存和渲染模型几个步骤,经过分析发现主要的瓶颈在网络请求和网格解析两个部分,所以整体的优化思路就是减少网络请求资源的体积和提升网格的解析速度。pjK28资讯网——每日最新资讯28at.com


pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

三、缩小模型的体积

3.1 常见的解决方案

目前主流的压缩方案是使用google的draco库对模型进行压缩。draco的原理类似降低图片的分辨率,通过减少模型的顶点数起到压缩体积的效果。pjK28资讯网——每日最新资讯28at.com

也就是说draco是一种有损的压缩方式,这样就会带来诸多的问题pjK28资讯网——每日最新资讯28at.com

  • 可能在网格连接处存在画面模型撕裂。
  • 仅仅压缩顶点只能将50.7mb的人物模型压缩到49.5,压缩效果有限。
  • draco前台decoder在h5中的解算效率不理想,可能节省下来的网络请求时间还没有增加的数据解算的时间长。

基于以上几点,最终我们放弃了draco的压缩方案。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

使用draco压缩之后导致的模型撕裂pjK28资讯网——每日最新资讯28at.com

3.2 进阶方案

高端的食材,往往只需要采用最朴素的烹饪方式。经过一些尝试,我们发现将glb模型直接打成zip包可以明显的提升模型的压缩效率。50.7mb的人物模型可以压缩到11.6mb。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

但是Three.js提供的gltfloader是不能直接加载zip文件的,于是我们需要对其进行功能扩展。pjK28资讯网——每日最新资讯28at.com

Three.js加载gltf模型是首先通过fetch请求获取到模型的arraybuffer,再对arraybuffer进行格式化。所以我们只需要在模型格式化之前拦截zip文件进行解压缩即可。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

于是我们使用jszip,资源加载完成后判断资源的后缀,如果是zip文件就使用jszip进行解压缩。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

看起来还不错,在保证视觉效果的同时又可以大幅压缩模型的体积,那么有没有可能做的再极致一些呢?pjK28资讯网——每日最新资讯28at.com

既然是针对性的场景,我们就可以从解压缩的解算开始入手,于是我们使用rust写了一个解压工具,将其转换成wasm包代替jszip,可以发现wasm的冷启动性能确实要比js好很多,可以将解压的时长从几十到100毫秒降低到1毫秒左右,适合体积比较小的解压缩场景。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

四、文件的加解密

作为一个h5项目,获取到静态资源的链接并不困难,所以需要对模型文件进行一点点加密,让破解起来没有那么容易。同时解密的过程不能显著延长资源加载的时间,影响用户体验。pjK28资讯网——每日最新资讯28at.com

基于数据解密的效率,我们可以截取文件buffer的一部分进行加密,而不对全文进行加密,同时将数据解密的过程也放到wasm中,提升解算效率的同时也增强了安全性。采用对称加密的算法,同一个方法既可以用于加密,也可以用于解密。pjK28资讯网——每日最新资讯28at.com

按照模型加载的流程,解密的操作应该放在解压缩之后,序列化之前,那么如何判断数据是否进行了加密呢,可以通过判断解压数据decode以后是否有glTF的标记来确定。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

如下图,数据解密的耗时几乎可以忽略不计,可以放心使用。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com


pjK28资讯网——每日最新资讯28at.com

五、如何优化首帧的渲染体验

优化完模型的加载,继续来优化模型的渲染,在加载一个体积比较大的模型的时候经常会有页面的卡死的情况出现,需要从两方面治标也治本的进行优化:pjK28资讯网——每日最新资讯28at.com

  1. 通过减少页面的卡停来优化用户的感官体验。
  2. 通过缩短首屏渲染的时长来解决根本问题。

5.1 减少页面的卡停

在模型加载的时候通常会设置一个loading页面来展示当前的加载进度,同时loading页也可以播放一些动效或者互动来让用户等待的过程中不那么无聊。但是由于js单线程的特性,在进行首帧渲染的时候任何事件都不无法响应,会让用户误以为页面卡死,造成流失。pjK28资讯网——每日最新资讯28at.com

为了解决这个问题我们可以使用分步加载的方案,在模型加载的时候先遍历第一层网格,将所有的网格隐藏起来,然后循环这些网格,每展示一个就执行一次render方法,这样就可以把一个大的卡顿分散成多个小的,不至于影响前台的体验。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

但是这样的方法只能让用户感受起来没那么卡顿,该等的时间一点没少,过长的等待时间还是会让用户等的不耐烦,有没有其他解决卡顿的方式呢?这就要从Three.js的渲染逻辑来进行分析了。pjK28资讯网——每日最新资讯28at.com

5.2 缩短首帧渲染的时间

由于我们做的是一个捏脸的项目,通过形态键来实现不同的脸型,表情等表现。在Three.js中存储形态键信息的属性在geometry.morphAttributes中,形态键存放的顶点信息总数与网格的顶点数相同,这就意味着同一个模型有多少个形态键,就额外需要加载多少套网格的顶点信息。在首次渲染的时候Three.js会遍历每一个形态键的顶点信息,生成一个float32array,而这个巨量的遍历操作就是造成卡顿的根本原因。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

如何解决这个循环黑洞呢,我想到了steamdeck上的着色器预缓存,通过将着色器编译的结果进行持久化,缩短页面加载的时间。那么我们只要将每一个网格的形态键编译的结果储存起来就行了。pjK28资讯网——每日最新资讯28at.com

/three/src/renderers/webgl/WebGLMorphtargets.jspjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

通过这种方式成功的将首帧渲染的时间从7秒缩短到0.6秒,大幅的提升了用户的体验。pjK28资讯网——每日最新资讯28at.com

讲到这里,大家可能发现了,虽然首帧渲染的时长缩短了,但是形态键缓存的资源有80mb,压缩后也有15mb,这块的时长可不可以继续压榨呢,先看一下资源的处理流程,处理解压后的文件需要将文件解析成JSON字符串,然后在转换成float32array,这里耗时最大的点就是JSON.parse的操作,有没有更好的方式处理呢,可以将这部分内容丢到rust里面,平均可以减少0.5s的时间。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

六、总结与规划

以上就是我们的优化流程,将glb模型文件压缩成zip包,配合前台wasm解压工具降低模型的加载时间。通过增加形态键缓存的方式来降低首帧渲染的时长。pjK28资讯网——每日最新资讯28at.com

图片pjK28资讯网——每日最新资讯28at.com

经过这一系列的操作,成功的将模型的体积从50mb压缩到11mb,增加了额外80mb的形态键缓存也可以使用zip压缩到15mb,处理后页面的首次加载时长从15秒缩短到5秒,算是一个不小的提升。pjK28资讯网——每日最新资讯28at.com

然而,我们也意识到还有进一步的优化空间,譬如目前虽然有了形态键缓存,但是原模型中的形态键信息还存储在模型中,这一部分的信息不需要被threejs读取,却很大的占用了模型的体积,后续可以开发一个gltf-pipeline类似的处理工具,将形态键缓存直接整合进gltf模型中,同时把整个模型的序列化工作放到wasm中处理,降低模型的尺寸的同时也可以减少模型解析的时长。期待为大家带来更好的使用体验。pjK28资讯网——每日最新资讯28at.com


pjK28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-101717-0.html基于 Three.js 的 3D 模型加载优化

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Java 函数式接口,一文彻底剖析!

下一篇: 深入探索 Vite 的热更新(HMR)实现

标签:
  • 热门焦点
  • 直屏旗舰来了 iQOO 12和K70 Pro同台竞技

    旗舰机基本上使用的都是双曲面屏幕,这就让很多喜欢直屏的爱好者在苦等一款直屏旗舰,这次,你们等到了。据博主数码闲聊站带来的最新爆料称,Redmi下代旗舰K70 Pro和iQOO 12两款手
  • 一篇聊聊Go错误封装机制

    %w 是用于错误包装(Error Wrapping)的格式化动词。它是用于 fmt.Errorf 和 fmt.Sprintf 函数中的一个特殊格式化动词,用于将一个错误(或其他可打印的值)包装在一个新的错误中。使
  • Flowable工作流引擎的科普与实践

    一.引言当我们在日常工作和业务中需要进行各种审批流程时,可能会面临一系列技术和业务上的挑战。手动处理这些审批流程可能会导致开发成本的增加以及业务复杂度的上升。在这
  • 多线程开发带来的问题与解决方法

    使用多线程主要会带来以下几个问题:(一)线程安全问题  线程安全问题指的是在某一线程从开始访问到结束访问某一数据期间,该数据被其他的线程所修改,那么对于当前线程而言,该线程
  • 破圈是B站头上的紧箍咒

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之每年的暑期档都少不了瞄准追剧女孩们的古偶剧集,2021年有优酷的《山河令》,2022年有爱奇艺的《苍兰诀》,今年却轮到小破站抓住了追
  • iQOO Neo8 Pro即将开售:到手价3099元起 安卓性能最强旗舰

    5月23日,iQOO如期举行了新品发布会,全新的iQOO Neo8系列也正式与大家见面,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更
  • 机构称Q2全球智能手机出货量同比下滑11% 苹果份额依旧第2

    7月20日消息,据外媒报道,研究机构的报告显示,由于需求下滑,今年二季度全球智能手机的出货量,同比下滑了11%,三星、苹果等主要厂商的销量,较去年同期均有下
  • 英特尔Xe-HP项目终止,将专注Xe-HPC/HPG系列显卡

    据10 月 31 日消息报道,英特尔高级副总裁兼加速计算系统和图形事业部总经理 表示,Xe-HP“ Arctic Sound” 系列服务器 GPU 已经应用于 oneAPI devcloud 云服
  • 亲历马斯克血洗Twitter,硅谷的苦日子在后头

    文/刘哲铭  编辑/李薇  马斯克再次挥下裁员大刀。  美国时间11月14日,Twitter约4400名外包员工遭解雇,此次被解雇的员工的主要工作为内容审核等。此前,T
Top