2024 抖音欢笑中国年(五):Wasm、WebGL 在互动技术中的创新应用

news2024/11/16 16:32:51

前言

随着 Web 前端技术的不断发展,越来越多的新兴技术方案被引入到 Web 开发中,其中 Wasm 和 WebGL 作为前端领域的两大利器,为开发者带来了更多的可能性。

本文将结合2024 年抖音欢笑中国年的部分项目,重点介绍如何利用 Wasm 和 WebGL 对目前流行的一些前端互动技术(比如 Lottie、渲染引擎、动画图片等)进行创新和实践,利用 Wasm 和 WebGL 等新技术方案的特性和优势提升业务性能和流畅度,给用户带来更好的体验。

Simple 渲染引擎

WebAssembly(Wasm)是一种可以在 Web 浏览器中运行,提供比 JavaScript 更高的性能,并且支持多种编程语言的全新的字节码格式;基于其高性能的优势,我们团队尝试将其应用到渲染场景中,推出了基于 Wasm + WebGL 的高性能、轻量化的 Simple 渲染引擎。

以期借助于 Wasm 的高性能计算,以 Simple 引擎为基础,保持轻量化的同时,解决目前前端动效和轻互动场景主流技术方案如 Lottie 动画、动画图片(序列帧、 Apng 、WebP)、JS 渲染引擎等存在的能力受限、资源体积大、性能较低等问题。

引擎架构

考虑到前端用户学习和使用成本,Simple 引擎使用 TypeScript 语言开发上层接口,主要是利用 TS 封装简单对象,同时做类型提示方便前端用户使用,另外还提供尽可能高性能的方式和 Wasm 进行交互;底层则使用 C/C++,主要处理计算工作,比如:矩阵计算、图形计算、动画计算、动态合批等;

Simple 引擎目前的渲染管线主要以 2D 为主,也分为两部分:JS 部分负责处理数据量少但是 GL 调用频繁的操作,Wasm 部分则相反负责处理数据量多但是 GL 调用少的操作,尽可能达到性能最优解。

整体架构如下:

0b7490e96201ec48415abe448e6f41a3.png

性能收益

受益于 Wasm 的计算性能优势,Simple 引擎相比主流的 JS 渲染引擎,比如:PixiJS 6.3、Cocos 2.4 在 Spine 动画、精灵旋转、精灵跳动、图形水平移动等基准性能测试场景中取得了不俗的表现:

41134740c43c0f8270a2ceab7ee62943.jpeg

以上测试数据来自 Android OPPO Find X1 抖音 跨端框架 V8 环境,可以看到基于 Wasm 的 Simple 引擎相比基于 JS 的引擎性能提升明显,计算任务越复杂,性能收益越大

计算任务复杂度:骨骼动画 > 图形计算 > 旋转变换 > 位移变换

测试代码

100 个 Spine 动画 Simple 和 Cocos 2.4 测试代码如下:

  • Cocos 2.4

875be47a74bc90af5cb69348e23a163c.png
  • Simple

948015216feb3cc8f58f77b0b5edb2eb.png

兼容性

从 2015 年 Wasm 项目正式启动到现在,经过多年的发展 Wasm 规范不断完善和扩展,目前主流的浏览器已经全面支持 Wasm 技术;同时 Simple 引擎最早在 2022年7月启动,之后在直播、财经、头条、音乐、小说等多个业务场景中落地,并在 2024 年初获得了在春节项目中应用的机会。

从数据来看抖音跨端框架中使用 Wasm 的用户占比高达 96.97% ,对于不支持 Wasm 的情况也可以使用 Simple 引擎编译的 asm.js 版本来进行降级。

经过一年多的反复实践与验证,总得来说 Simple 引擎兼容性表现稳定可靠。

Lottie WebGL 渲染

Lottie WebGL 渲染是利用上文提到的 Wasm + WebGL 渲染引擎去渲染 Lottie 动画的方案,在几乎完美还原 Lottie 动画的基础上,利用引擎封装好的相关机制(事件、渲染对象)扩展 Lottie 动画的交互控制能力,丰富其特性支持,以及基于 Wasm + WebGL 渲染提升动画性能。

性能收益

Lottie 是动画 Airbnb 公司开源的跨平台动画框架,支持将 AE 中设计的动画导出为 Json 协议,是前端最流行的动画协议;但是在 Web 上官方只提供了三种渲染方式(SVG、Canvas 2D、HTML),并没有支持 WebGL:

2bdb4f1052a0931cbec0a992a4c85600.jpeg

而前端最流行的那些 JS WebGL 渲染引擎也没有直接支持 Lottie 动画,这就会带来三个问题:

官方渲染方案性能低

SVG、HTML 不适合处理大量元素的动画,而 Canvas 2D 的使用方式决定了它很难充分利用缓存机制,因此官方提供的这三种渲染方案其实性能是偏低的,会在较多、较复杂动画场景遭遇性能瓶颈。

0f212bf8c21d1df5ac9abe326db87ee2.jpegcb5db40736d2d31bf205c7617dad93a6.png

如上图所示某 Lottie 动画在 Chrome 6 倍降速模拟移动端设备的性能表现,Lottie SVG 每帧耗时 5.77 毫秒,而 Simple Lottie 每帧耗时仅 1.10 毫秒,性能提升近 6 倍。

离屏 Canvas 渲染性能低

目前主流的 JS WebGL 渲染引擎只能使用离屏 Canvas 的方式去渲染 Lottie 动画,这种方式需要先创建一个离屏的 Canvas 然后用 Lottie 官方提供的 Canvas 2D 方式把动画的当前状态渲染到离屏 Canvas 中,接着再把这个离屏的 Canvas 用纹理的方式上传到 GPU,如果动画更新还需要重复这个流程。

相对复杂的渲染流程会导致其性能较低:

bfc872288ec0fecc293985c55391846d.png

1b88f7c5e69fb147c2f2931f9e7681dd.png

如上图所示,12 * 18 个 Lottie 动画在 i7 Mac Chrome 上测试,右侧 WebGL 直接渲染 Lottie 动画比左侧离屏 Canvas 渲染帧数高了 35 fps,性能提升近 3 倍。

JS 图形计算性能低

提升 Lottie 动画性能,除了要考虑渲染性能,还需要考虑计算性能,比如上面两个例子中的 Lottie 动画更多是图片元素,但是矢量图形也是 Lottie 动画中非常重要的功能。

如果基于目前主流的 JS WebGL 渲染引擎去渲染 Lottie 动画,在以矢量图形为主的 Lottie 动画中对比 Lottie 官方提供的 SVG 或者 Canvas 甚至会出现性能劣化的情况:

d934ff9f49eab98c6e3a59b8d419940b.jpegc6801d39ecbae9a9050184ca80628455.jpeg

可以看到左侧 SVG 在动画峰值每帧仅需 6.26 毫秒,而右侧 PixiJS 在动画峰值每帧需要 11.68 毫秒。

基于 JS WebGL 渲染引擎渲染 Lottie 动画在矢量图形场景出现性能劣化最主要原因在于 SVG 的计算在浏览器封装的 Native 模块中进行,而 JS WebGL 渲染引擎的计算在 JS 中进行,哪怕是几乎优化到极致的 PixiJS 受限于 JS 也只能在图片元素等部分 Lottie 动画中取得性能优化收益;因此只有采用 Simple 引擎这种 Wasm + WebGL 的方案才能彻底、全面优化 Lottie 动画的性能

905f5c96220564096eae1925f85e8ce6.png

相同场景 Simple Lottie 在动画峰值每帧仅需 5.35 毫秒(这其中还包含了 JS 动画参数插值计算部分,后续这部分 JS 计算也下沉 Wasm ,整体估计还能优化 1 毫秒 )。

交互控制

使用 Simple 引擎直接去渲染 Lottie 动画,除了性能上的收益之外,还利用引擎提供的能力增加了很多交互控制上的便利,比如:素材替换、事件监听、动画混合、文字变更、物理碰撞等等。

在 2024 年春节群红包雨项目中几乎全部的素材都是 Lottie 动画素材:

4af8e382b0d1c28e3969993e3d7f697f.png

0736769d7b4100ed9acc77a2abe4b0b8.png

静态的 Lottie 素材结合 Simple Lottie 提供的动态交互能力就可以很方便的实现诸如红包点击、红包动态纹理、点中动画动态文字、大红包点击、连击动画动态数字等等。

举个例子,用户点中红包雨之后需要播放一个动画,整体是一个烟花的效果,需要随机展示不同的文字:

7e42529a36aea53847702d1aa412fe34.jpeg

对于这个需求,设计同学只需要提供一个固定的 Lottie 动画,然后再提供一些其它的文字素材;开发则需要在代码中首先从动画中查找到文字精灵,然后随机选取一张文字纹理,最后更新文字精灵的纹理即可。

b88a62f521e5a8fb9a137b56ca561889.png

特性支持

使用 Simple 引擎去渲染 Lottie 动画,还能在原有 Lottie 特性支持的基础上增加更多的能力。比如从动画素材上来说我们可以把原始 Lottie 动画产物中零散的图片合成一张雪碧图,减少资源请求数量,减少纹理个数,提升渲染性能:

e0251a69adabb2f0b55642088645813d.png

33136a79d563d4896cc8b666746a30e0.png

左侧是散图,右侧是雪碧图。除此之外甚至还能把图片转成压缩纹理,减少内存占用和加快渲染速度。

除了动画素材上的优化,还能给 Lottie 动画增加更多的渲染效果,比如:

粒子
6d1955696c83244ab161c9acdf71c793.jpeg
滤镜

Simple 引擎通过 Shader 实现了很多常用的滤镜效果,比如:

53c37f51345b32b0de9a5a3b8d50960b.png

d73d0a4e76634cf802a40700847c1089.png

左侧是模糊效果、右侧是颜色卷积效果。

自定义效果

基于 Simple 引擎提供的 WebGL 能力封装,还可以实现更多更丰富的自定义效果,比如:透明视频以及下面将要介绍 WebGL 帧差序列帧。

WebGL 帧差序列帧

帧差序列帧是一种基于 WebGL 1.0 标准的动画图片规范,由首帧图片、帧差图片(不透明帧差、半透明帧差)、帧差配置信息组成,一般包含 4 个文件:

2abdb79a4955255221847c183283e2a9.jpeg

背景

由于原始 Lottie 动画只支持少部分 AE 特性,对于不支持的特性设计师往往会把这些效果转成序列帧实现,这就会导致动画素材产物体积增加。而另一方面目前常用的视频、Apng、WebP 这些主流素材又各有各的问题,比如:

  • 视频存在兼容性问题、不能交互、对低端机来说存在一定的性能压力;

  • Apng、WebP 这些传统动画图片格式基本没怎么考虑帧间压缩:

4d659f28793f06ffe423fa7cb9a3393f.png

上图是一张 Apng 解码后的信息,IDAT 表示首帧、fdAT 表示后续帧,可以看到后续帧和首帧几乎一样大,也就是说对于这个素材生成的 Apng 效果和简单拼接的原始序列帧差不多。

资源体积优化

基于上述现状,如果能基于兼容性最好的 WebGL 1.0 标准去实现一些类视频的简单自定义帧间压缩算法, 就能在动画场景以更小的资源体积完美替代序列帧、 Apng WebP

2930afdb287ee8bb16d8288ad34ffa99.jpeg

对于一般素材帧差序列帧在体积上相比序列帧、 Apng WebP 会减少 50% 左右。

交互能力

帧差序列帧还能以更高的性能和提供任意时刻切任意帧的能力,实现一定的交互能力,从而满足一些轻互动场景的需求,对视频和 3D 模型形成差异化优势。

4f7127c6c4a27395de8120b1075cecf1.png

6668d3da94f67114b3a591786fc5c95e.jpeg

caa532be53baea4b0ac369d18729ddff.jpeg

我们以小火人、打年兽和徽章项目为例:

  • 小火人、年兽的动画状态是会随着用户的操作发生变化的,而视频是很难实现无缝的帧切换;

  • 徽章需要 360 度旋转展示,同时还需要响应用户的滑动操作,一般情况下这里只能使用 3D 模型,那么整个项目就得以传统 3D 项目的流程去做,一方面成本会高出很多,另一方面考虑实时渲染性能压力,效果上可能还做不到百分百还原。而采用帧差序列帧的方案去做,项目成本就会低很多,同时效果上也不会有任何折扣。

未来展望

以上即是我们团队在 Wasm 和 WebGL 上的一些尝试与思考,虽然取得了一定的突破,但是方案本身还有很多需要优化和完善的地方:

  • Wasm 标准依然在继续更新,SIMD、线程、垃圾回收、WASI 等新特性会进一步提升性能,同时可能会对现有引擎架构的升级产生很大影响;

  • 帧差序列帧目前的帧间压缩效率只是优于序列帧、Apng、WebP,和视频相比还有很大差距;在保持现有优势的前提下怎么更接近视频是充满挑战的问题;

  • Lottie 动画性能得到了优化,增加了很多能力;这些能力怎么高效率的开放给设计和开发去使用,怎么改进现有工作流效率,动效、轻互动的完美工作流需要满足哪些标准等等。

欢迎大家和我们团队一起探索和交流,共同推进技术的发展。

团队介绍

我们是抖音前端架构-互动体验技术团队,主要为字节跳动业务提供互动技术解决方案。技术产品包含面向互动 / 小游戏研发场景的 SAR Creator、高性能动效渲染引擎 Simple Engine、互动场景端能力套件 AnnieX 互动容器

在这些技术建设与业务落地上,和抖音前端-互动创作团队跨端框架团队、开放平台小游戏团队、用户增长-激励前端团队一同推进,不断探索字节跳动应用生态下的创新业务形态。

下期预告

下期主题是前端互动场景中的性能优化,将介绍前端互动页面在与宿主端共享有限进程资源的场景下遇到的性能问题及相应的解决方案,敬请期待。

往期回顾

2024 抖音欢笑中国年(一):招财神龙互动技术揭秘

2024 抖音欢笑中国年(二):AnnieX互动容器创新玩法解析

2024 抖音欢笑中国年(三):编辑器技巧与实践

2024 抖音欢笑中国年(四):渲染技术实践与探索

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1605394.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端三剑客 HTML+CSS+JavaScript ② HTML相关概念

他们这样形容我 是暴雨浇不灭的火 —— 24.4.18 学习目标 理解 HTML的概念 HTML的分类 HTML的关系 HTML的语义化 应用 HTML骨架格式 sublime基本使用 一、HTML初识 HTML指的是超文本标记语言,是用来描述网页的一种语言 HTML不是一种编程语言,而是一种标记…

C语言开发的医学影像数字化PACS系统源码 带三维重建和还原的PACS源码

C语言开发的医学影像数字化PACS系统源码 带三维重建和还原的PACS源码 PACS全称Picture Archivingand Communication Systems。它是应用在医院影像科室的系统,主要的任务就是把日常产生的各种医学影像(包括核磁,CT,超声&#xf…

CSS基础+基本选择器和复合选择器(如果想知道CSS的基础+基本选择器和复合选择器知识点,那么只看这一篇就足够了!)

前言:在我们学习完了html之后,我们就要开始学习三大件中的第二件—CSS,CSS 可以控制多重网页的样式和布局,也就是将我们写好的html代码加上一层华丽的衣裳,使网页变得更加精美。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨…

halcon瓶身表面缺陷检测-滤波差值法

前言 在瓶子,灌装产业中,通常需要瓶子的瓶身进行检测,防止其出现划痕,破洞等情况。但是通常瓶身出现的缺陷都非常小,往往只是一些细小的划痕,这种情况就非常容易被误判为OK情况。 所以采用滤波差值法&…

Stability AI 发布 SD3 API:开启人工智能新篇章

文章目录 1.Stable Diffusion 3 API开放了! 2.Stability AI Document地址3.获取API Key4.API方式调用SD3出图接口地址接口请求规范接口请求响应结果 5.Stable Diffusion 3.0、Stable Image Core、Fooocus 2.3.1、MidJounery效果查看 1.Stable Diffusion 3 API开放了! Stabilit…

js高级 笔记02

目录 01 object提供的一些静态方法 02 词法作用域 03 作用域链 04 arguments的使用 05 开启严格模式 06 高阶函数 07 闭包 01 object提供的一些静态方法 Object.create() 对象继承 Object.assign(对象1,对象2) 对象合并 可以将对象2 里面的可枚举属性和自身的属性合并到…

压缩感知的概述梳理(3)

参考文献 Adaptive embedding: A novel meaningful image encryption scheme based on parallel compressive sensing and slant transform 文献内容 梳理 列表形式 并行压缩感知核心元素与流程 信号 x 长度:N表示:(x \sum_{i1}^{N} a_i\psi_i \su…

软件测试面试:关键问题解析

在软件开发领域,测试是确保软件质量的重要环节。面试是评估软件测试人员技能和经验的关键时刻。在一个软件测试面试中,面试官通常会问一系列问题来评估面试者的知识、技能和解决问题的能力。本文将介绍一些常见的软件测试面试问题,并给出一些…

电脑开不了机?不要慌,三招教你快速解决!

电脑开不了机是我们在日常使用中可能遇到的一个严重问题,它会影响我们的工作和生活。了解如何解决电脑开不了机的问题对于维护电脑正常运行至关重要。本文将介绍三种常见的解决电脑开不了机的方法,帮助您快速恢复电脑的正常使用。 方法1:检查…

刷题日记——进制转换3(机试)

题目——进制转换3 锲而不舍——先给自己立一个纪念碑 思路 根据输入信息,将输入值从m进制转换成10进制将10进制数据转换成n进制数据输出 输入值从m进制转换成10进制 将输入值视作字符串 依次取出字符串字符, 如果是数字: 减去‘0’得到真…

初识 React:安装和初步使用指南

文章目录 前言一、React 是什么?1.组件化开发2.虚拟 DOM3.单向数据流4.生态系统丰富 二、安装1.准备工作2.下载react 三、探索 React 应用总结 前言 在当今的 Web 开发领域,React 已经成为了一个备受推崇的技术。它的组件化、灵活性和高效性使得它成为了…

栅格地图、障碍物地图与膨胀地图(栅格地图)

在ROS中,地图是非常基本的元素,特别对于2D激光SLAM而言,栅格地图可以说是必不可少的元素。机器人在需要前往目标点时,需要在栅格地图中找到一条合适的路径从当前点到达目标点,这部分内容在move_base中有了详细的接口&a…

MySql数据库从0-1学习-第五天事务和索引

事务 事务 是一组操作的集合,它是一个不可分割的工作单位。事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作 要么同时成功,要么同时失败。 注意事项,默认事务是自动提交的,也就是说,当执行一条DML语句,MySql会立即隐…

“低价竞争”仍在继续,分期免息成商家新武器

近日,在京东618商家生态伙伴大会上,京东推出各项政策,尽全力让所有合作伙伴赢在京东618、赢在京东。京东金融也将在618大促期间,为各位商家带来极具竞争力的金融产品和大促政策。 举例来说,大促期间,“京东…

分类预测 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机数据分类预测

分类预测 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机数据分类预测 目录 分类预测 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机数据…

小试牛刀!

1.从双倍数组中还原原数组&#xff08;力扣&#xff0c;vector&#xff09; java式c解法。 class Solution { public:vector<int> findOriginalArray(vector<int>& changed) {int n changed.size();if(n % 2 1) return {};map<int, int> mp;for(int c…

02 - Git 之命令 + 删除 + 版本控制 + 分支 + 标签 + 忽略文件 + 版本号

1 Git相关概念 1.1 以下所谈三个区&#xff0c;文件并不只是简单地在三个区转移&#xff0c;而是以复制副本的方式转移 使用 Git 管理的项目&#xff0c;拥有三个区域&#xff0c;分别是 Working area工作区&#xff08;亦称为 工作树Working Tree&#xff09;、stage area …

【Web】HTML基础

专栏文章索引&#xff1a;Web 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 一、HTML介绍 1.HTML 定义 2.标签语法 3.HTML 基本骨架 4.标签的关系 5.HTML 注释 二、标签 1.排版标签 1.1 标题标签 1.2 段落标签 1.3 换行标签 1.4 水平线标签 1.5 文本格…

【Spring】之基础概念和使用

&#x1f3c0;&#x1f3c0;&#x1f3c0;来都来了&#xff0c;不妨点个关注&#xff01; &#x1f3a7;&#x1f3a7;&#x1f3a7;博客主页&#xff1a;欢迎各位大佬! 文章目录 1. Spring的概述1.1 什么是容器&#xff1f;1.2 什么是IoC&#xff1f;1.3 什么是DI&#xff1f…

(二十八)Flask之wtforms库【上手使用篇】

目录&#xff1a; 每篇前言&#xff1a;用户登录验证&#xff1a;用户注册验证&#xff1a;使用示例&#xff1a; 抽象解读使用wtforms编写的类&#xff1a;简单谈一嘴&#xff1a;开始抽象&#xff1a; 每篇前言&#xff1a; &#x1f3c6;&#x1f3c6;作者介绍&#xff1a;【…