五福背后的 Web3D引擎Oasis Engine正式开源
发布日期:2021-03-01 14:03:20编辑:音乐人
Oasis 从开源走向新的起点,用 3D 化的交互和表达让世界变得更美好。
相信大家已经体验了今年支付宝五福的活动,无论是今年的五福首页还是打年兽游戏都是由蚂蚁互动图形引擎(代号:Oasis Engine)驱动的。
Oasis Engine 是蚂蚁集团 Web 3D 互动图形引擎,同时也是阿里巴巴互动技术方向的首选 Web 3D 引擎,已于 2 月 1 日正式开源。
这篇文章会和大家介绍 Oasis Engine 的一些概况和 Oasis Engine 的前世今生以及未来展望。希望通过这篇文章可以让大家对 Oasis Engine 有一个初步了解。
引擎介绍Oasis Engine 是引擎一款以 Web 为先,移动为先的互动/创作平台。使用组件系统架构,并且追求易用和轻量。Oasis Engine 主要包含 Oasis Runtime、Oasis Editor 和 Oasis Store 三部分。接下来我们会通过概述、功能介绍、稳定性和性能几个维度来给大家介绍引擎。
概述
Oasis Engine 采用组件系统架构,Oasis Engine 不仅需要具备三维渲染能力,还需要包含了非常多来自各领域的功能,比如 2D、3D、UI、音频、物理、VR/AR、逻辑编写等等,这些功能都是开发者的刚需。同时开发者在使用上也通常希望引擎的结构可以保持清晰,功能可以灵活组合。
除此之外,通常业务开发还希望进行功能沉淀,其实这些都是属于易用性的范畴。在如此功能复杂度和易用性的权衡下,我们选择了组件系统架构。在组件系统架构下,万物皆组件,任何功能都可以以组件的形式插拔,灵活组合。同时脚本也是一种特殊的组件,开发者也可以很自然的把业务功能沉淀为组件复用。
Oasis 引擎采用脚本系统进行逻辑编写。我们提供了非常多的脚本生命周期回调,开发者只需重载需要的回调函数即可。
从易用性和可读性来说,脚本相对通过事件编写逻辑都具有明显的优势。尤其在组件系统架构中,脚本系统是更自然的一种方式。包括我们在做引擎架构时也从不会认为任何一种架构有绝对的对错,更多的是权衡和适合的探讨。同时,我们在脚本系统也做了很多体验上的优化,比如提供了克隆装饰器,开发者可以根据属性的实际情况选择不同的克隆装饰器设置克隆模式,相对于手动编写克隆函数更加的易用。
Oasis 引擎的开发语言采用了 TypeScript ,TypeScript 是 JavaScript 的强类型超集,相比弱类型的 JavaScript 具有非常大的优势。尤其对于大型复杂项目,TypeScript 带来了研发效率提升非常明显。相信近几年很多前端开发者已经有所体会。我们也推荐开发者使用 TypeScript 编写逻辑脚本。
Oasis 引擎在 API 的设计上追求严谨性、简洁性、易用性等宗旨,听起来很笼统,但是这背后却是无数的设计细节堆积起来的。从体感的维度来讲,清爽、自然、易用、符合开发者直觉的 API 设计就是好设计。我们在 API 设计上还利用了大量现代化的语法特性,比如函数重载、装饰器、async/await、泛型等,这些语法对于 API 的设计非常重要,会直接提升用户的研发体验。
功能介绍
Transform 是引擎的高频使用功能,无论是渲染还是物理都需要 Transform 描述坐标等相关信息。所以一个优秀的 Transform 不仅要功能强大,还有具备良好的性能优化。
Transfrom 最显著的一个特点就是父变换会影响子变换,比如我们能想到修改父节点的局部位置会触发自身和子节点的世界位置变化。但是,实际情况可能远比这复杂,如果修改父节点的局部旋转,不仅会触发自身和子节点的世界旋转变化,还会触发自身和子节点的世界位置变化。同样修改局部缩放也有类似的效应。我们在 Transform 内部做了很多原子化的脏标记,基本原则就是不 get 属性不计算,如果 get 了属性也会根据脏标记判断是否要重新计算。
基于 WebGL 开发的引擎通常面临 JS 没有析构函数的困扰。引擎的显存对象并不在 JS 的托管范围之内,如果不进行处理就会造成显存泄漏。于是,Oasis 引擎提供了资源的手动释放函数,可以直接调用对象的销毁函数进行显存释放。但是实际问题更加复杂,当设计给开发同学一个模型时,我们并不知道这个模型对资源的引用关系。比如实体引用了材质,材质又引用了纹理,他们之间的引用关系错综复杂。首先,我们很难找到这些资源;其次,找到了也很难确保其没有被别的模型引用并进行安全销毁。
资源系统是引擎的基础能力,包含资源的加载和管理等职责。Oasis 引擎的资源系统加载 API 非常的简单易用,并且支持泛型、和异步编程。我们做了资源引用计数,开发者只需要关心实体节点的销毁即可,引擎内部会自动维护引用计数,调用 resourceManager.gc() 时,所有引用计数为 0 的资产会自动销毁,从而在功能性和易用性直接找到了平衡。
着色/材质系统是引擎的渲染心脏,其好坏一定程度上决定了引擎的健康发展。Oasis 引擎自定义着色器非常的简单,让开发者专注于着色器逻辑本身。着色器的数据设置也非常简单,只需调用 shaderData 中的相关接口即可。有过相关开发经验的同学可能还知道着色器宏功能,在 Oasis 中同样非常简单,只需调用 enableMacro 接口即可。引用内部会自动处理相关的子着色器编译。
除了简单,Oasis 的整个着色系统还非常强大,Oasis 还是一个面向 GPU 友好的引擎,不仅可以通过材质设置着色数据,还可以通过场景、渲染器、相机等对象设置着色数据。另外,还可以非常自然地把蒙皮计算、粒子轨迹计算、材质着色等模块放入 GPU 中执行,充分发挥 GPU 的并行运算能力。
除了自定义着色器之外,Oasis 引擎还提供了灵活强大的 BufferGeometry 系统,开发者可以使用该系统自定义几何体数据。BufferGeometry 系统支持交错顶点缓冲、独立顶点缓冲、instance 缓冲和索引缓冲,做过底层图形开发的同学可能会非常熟悉这些功能。Oasis 的 BufferGeometry 系统几乎包含了所有 GPU 相关的几何体数据处理能力。引擎包含简单易用的功能是必须的,如果能同时兼顾灵活和强大那自然是极好的。
我们来说说 BufferGeometry 具体可以做什么,其实高级开发者可以使用它接入任何自定义粒子、拖尾之类的功能。比如 Mars 组件和 Spine 组件就是采用 BufferGeometry 系统接入的。Mars 也是蚂蚁集团的一款高性能动画和特效软件,Spine 想必大家都很了解了,一款非常流行的 2D 动画软件。
稳定性和性能
稳定性和性能对引擎来说非常的重要,我们在稳定性和性能方面付出了非常多的努力,在亿级流量的平台项目上 crash 率小于万分之 0.3 :
测试方面,我们在编写每个功能的同时都会增加对应的单测案例,在 github 也部署了自动化 CI 测试。 性能优化方面,我们也付出了非常多的努力,比如组件驱动的相关优化、Transform 优化、显存上传优化、数学库优化等等。 内存优化方面,我们提供了 GPU 纹理压缩功能,可以让纹理显存降低约80% ,同时还提供了良好的资源 GC 管理机制。在每一个系统设计上,我们都会综合考虑性能和内存的平衡点,不会极端盲目的使用“空间换时间”。
再来说说我们目前的性能现状,基于上图中的性能测试案例,和国外知名 Web3D 引擎也进行了性能对比,同样的测试规模和环境,Oasis 的性能大约是国外知名 Web3D 引擎的 2 倍。虽然这个案例并不是很全面,但至少是某几块功能的综合性能表现。
总结
最后,我们对引擎介绍进行一下总结,Oasis 引擎采用组件系统架构、逻辑编写采用脚本系统、引擎源码使用 TypeScript 编写。功能上,我们介绍了引擎的几个基础系统,分别是 Transform 系统、资源系统、材质/着色系统和 BufferGeometry 系统,相信后续还会有机会和大家进行更多的功能介绍;稳定性和性能方面,具备金融级稳定性和领先的性能。
前世今生接下来,我们介绍一下 Oasis 引擎的前世今生,套用王小波的“时代三部曲”,将 Oasis 引擎发展至今分为三个阶段:黑铁时代、青铜时代和白银时代。
黑铁时代第一阶段是“黑铁时代”(2016年-2018年)。2016年,阿里巴巴和蚂蚁的移动端业务蓬勃发展,但是面向互动需求的图形技术还比较落后,以 Web 3D 引擎为例,长时间内都依赖并不是为移动端而生的 Three.js 引擎。在资产标准方面,glTF 2.0 还没有诞生,obj + mtl 这种古老的格式还不支持 PBR 等高级材质的能力,虽然 fbx 设计师导出方便,但因为其体积过大和 Three.js 的加载器不稳定导致很多项目在美术资产进引擎阶段就流产。
2016年底,蚂蚁图形引擎史上第一位英雄出现,景夫(蚂蚁高级图形技术专家、仙剑三主程、R3 核心开发者)写下了第一行蚂蚁图形引擎的代码,这个项目被命名成 R3(意为 Render for 3D)。R3 为蚂蚁移动端的互动业务而生,采用行业里先进的组件系统游戏引擎架构,工程上为了追求运行时体积的最小化,使用流行的 monorepo 多包单仓库的开发模式。为了更方便地解决场景编辑问题,R3 也定义了一套自己的开发工作流,采用行业里领先的 Unity 编辑器作为场景编辑器,通过自研的 Unity 插件导出 glTF 文件,供运行时加载解析成场景。
黑铁时代留下了几个经典的作品,今天打开蚂蚁庄园的“运动会”面板,依旧能看到这这些 low ploygon 风格的游戏。“星星球”是第一个使用 R3 引擎的互动游戏,甚至当时还开发了 AR 版本,比较先锋。
青铜时代
第二阶段是“青铜时代”(2018年-2020年)。蚂蚁图形引擎从体验技术部移交到了业务场景更加丰富的 RichLab 团队,从 R3 升级为 Oasis,新团队开始重新思考图形引擎之于蚂蚁互动业务和前端工程师的意义。在移动支付和金融数字化的背景下,移动端业务大量的富交互场景需求开始涌现,而对于稳定性的要求非常苛刻。为了更快更好地解决业务诉求,我们一方面开始拥抱前端生态:
用 Typescript 重构引擎,使引擎的代码更加健壮,同时开发者可以获得更好的代码提示体验;
融入蚂蚁前端开发框架,让引擎能够自然地运行在 React 等框架中,并且拥有资产沉淀能力;
和客户端以及小程序容器的同学合作适配了支付宝小程序,让引擎能够在更多的环境中运行。
另一方面,我们把重心放到了 3D 研发提效上。通过自研的 Oasis Editor 云端场景编辑器,我们实现了资产管理、场景编辑器、脚本编写等核心能力。同时,我们也关心工作流上下游的衔接问题,比如美术资产的导入问题,我们建议使用 fbx 文件作为输入,然后通过云端的资产转换和压缩等能力处理成适合运行时加载的文件;又比如,我们提供不同产物导出的能力,有 React/Rax/小程序等,实现一处开发多处部署。
白银时代
第三个时代是“白银时代”(2020年-?)。蚂蚁图形引擎史上的第二位英雄出现,尘沫的加入就如普罗米修斯神话为 Oasis 引擎的重生带来了火焰。经过八个月的四次迭代,引擎的功能、性能和易用性都发生了质的变化:
功能方面,引擎的实体/组件系统、脚本系统、资源系统、材质/Shader 系统等基础系统能力达到了行业先进水平; 易用性方面,对引擎的核心系统进行了重新设计和思考,API 细节上完全抛弃了之前组件用对象传参的模式,通过 set/get 属性来控制,充分利用 Typescript 语言的特性,让开发者充分享受到“猜测 API”的爽快感; 性能方面,引擎的综合性能增强到了青铜时代的四倍,其中 BufferGeometry 系统、材质/Shader 系统的单项性能均达到了之前版本的十倍以上,大幅领先国外知名 Web 3D 引擎。
除了在技术上的不断升级,Oasis 团队也非常重视业务落地,我们服务了阿里巴巴和蚂蚁集团内众多事业部的项目,在各个业务方中获得良好的口碑,在各个客户端中也验证了引擎的兼容性和稳定性。
未来展望
白银时代也是一个开源的时代,事实上 Oasis 引擎的研发迭代早在青铜时代就进入内部开源,按照开源的工作模式通过里程碑和 issue 管理功能迭代。如今引擎虽然在基础功能上已经能够满足业务需求,但未来我们希望把引擎放在一个更大的舞台,通过开源的方式把引擎的能力进一步增强。比如物理引擎方面,目前我们正在通过 WebAssembly 的方式将其集成到引擎中。在引擎的完整性方面,我们首先会补充 2D 图形的能力,同时让引擎能够渲染更多互动中所需的精灵类型,比如 Spine 和 Lottie;更远的目标是实现引擎的跨平台,虽然目前仅支持 WebGL 1.0 和 2.0,但可以看到引擎的 API 如 WebCanvas 等都已经是跨平台引擎的接口设计了,未来会根据需求优先级实现 Metal/Vulkan/WebGPU 等新型图形语言接口的接入。
坦白来说, Oasis 还处于发展期,今天开源也只是 Oasis 新的起点,未来还有很长的路要走。希望 Oasis 引擎可以用自己的方式为国产 3D 引擎事业尽一份力,也希望 Oasis 团队可以不忘初心,我们将用 3D 化的交互和表达让世界变得更美好,实现我们心中的绿洲。