蚂蚁金服 Web 3D 技术探索之路 - SEE Conf

蚂蚁金服 Web 3D 技术探索之路 - SEE Conf

开场

大家好,我是蚂蚁金服 Oasis 3D 负责人 烧鹅,很荣幸能在 SEE Conf 跟大家分享我们在 Web 3D 的实践。

我们团队一开始是为了提升互动类产品的趣味性和商业转化数据,开始储备 3D 图形技术的开发能力。刚开始我们做了一系列的技术调研,像基于 Web 的方案 ThreeJS、BabylonJS,虽然开源多年拥有发达的社区,但是一开始并不是“移动优先”(Mobile First)考虑,而且编辑器功能也很弱,并不满足实际开发的需求;另外,基于的 Native 的方案 Unity、Unreal 等更面向游戏开发者,之于传统的前端工程师上手成本太高,而且通过 WebAssembly 方案导出的产物太大(几百M),并不是适合 Web 环境加载运行。

因此,我们决定深耕 3D 图形技术,打造面向蚂蚁金服前端工程师且适应蚂蚁未来业务发展的 3D 技术产品:Oasis 3D。“Oasis”这个名字取自电影《头号玩家》中的大型虚拟世界“绿洲”,Web 3D 的世界就像一片荒漠,我们希望有一天能把它变成绿洲——这是我们的愿景

Oasis 3D 是一个面向前端工程师的综合性 3D 解决方案,由引擎和配套工作流组成,我接下来会着重介绍这两部分。

Oasis 3D 引擎

引擎部分,我会从架构、渲染、动画三方面介绍。

架构

Oasis 3D 引擎实现“Do one thing, Do it well”的微内核架构,分为渲染管线、资产管理、设计模式、能力扩展等四层,每个层中的模块都是一个独立的包,通过 AliNPM 托管,并使用 Lerna 来管理包之间的依赖,具备低耦合、易扩展等特点。除了每个包可以独立维护,比如更好地写单测之外,通过强大的“能力扩展”不断地衍生出新的模块,并可以像乐高积木一样组装出适合不同业务的 3D 引擎,比如工业产品渲染引擎、 3D 地理可视化引擎。

上述四层中,“能力扩展”是引擎面向开发者的核心概念。以下图的“跳舞的蚂蚁”为例,要实现这样的效果需要以下四部分能力:

  • Model:模型能力,用来负责模型的加载和解析,目前我们使用的 glTF 标准模型格式;
  • Transform:变换能力,就是位置、旋转、缩放的集合(简称TRS);
  • Render:渲染能力,比如使用 WebGL 渲染的能力;
  • Animation:动画能力,这里指的是骨骼动画的播放;

这几个能力是引擎中的内置能力,可以通过编写简单的过程式代码实现单个节点能力的增加,不需要某种能力也可以很方便地删除代码。可能有人会问:如果想自定义能力该如何实现? Oasis 3D 引擎提供了自定义能力扩展,基于 Nodeability 这个基类可以快速扩展出自己想要的能力,比如想给上面的蚂蚁增加一种“麦克杰克逊”的太空漫步的能力,可以这样写代码:

// “麦克杰克逊”能力
class MichaelJacksonAbility extends NodeAbility {
  constructor(node) {
    super(node);
    this._time = 0;
  } 
  onUpdate(deltaTime) {
    this._time += deltaTime;
    let x = Math.sin(this._time * 0.001) * 4;
    this.node.position[0] = x;
  }
} 
// 扩展“麦克杰克逊”能力
antNode.createAbility(MichaelJacksonAbility);

NodeAbility 是所有能力的基类,可以通过在它的生命周期钩子函数 onStartonUpdateonDestroy 里编写代码实现想要的功能。

渲染

渲染是一个 3D 引擎比较核心的部分,也是多数人望而生畏的部分。Oasis 3D 的渲染管线设计简洁,首先引擎通过浏览器提供的 requesetAnimationFrame API 启动一个主循环,渲染器负责递归场景树中的节点并遍历更新其各种能力的属性;然后通过 glTF 提供的3D场景信息和基于物理渲染(Physically based rendering)的材质解析生成图元(点、线段或三角形,一般指三角形)和PBR材质,渲染硬件接口(Render Hardware Interface)封装了 WebGL 1.0 的API,负责图元和材质的绘制。

巧妇难为无米之炊,glTF 就是 Web 3D 世界的“米”,由 WebGL 官方组织 Khronos 提出,是 Web 3D 标准的场景格式。它是图元和材质的输入,主要由一个描述场景结构的JSON文件和一个包含几何体、骨骼动画和蒙皮等信息的二进制文件组成。

PBR 材质是 Oasis 3D 引擎目前主要使用的材质,和传统的简单材质如 Bling-Phong 的区别在于它遵守能量守恒定律。举个简单的例子,光线射到一个物体上,高光部分的光斑越小就越亮,而 Bling-Phong 材质的实现只是漫反射、镜面反射等值的简单叠加,并没有遵循能量守恒定律。我们目前使用的是2013年由迪斯尼公布的Cook-Torrance BRDF 算法,这个算法的 fragment shader 实现代码将近1000行。虽然 PBR 材质的算法比较复杂,但是应用层暴露的 API 很简单,这也是 PBR 受欢迎的地方。

终于讲到了硬件渲染接口(Rendering Hardware Interface,简称 RHI),相信不少人都尝试学习过 WebGL,网上很多教程都会讲如何绘制一个三角形,上来就是一坨代码,大部分人还没入门就放弃了。WebGL 的 API 大概有满满的两页,如果没有好的封装,写起来十分费劲。 Oasis 3D 引擎 RHI 的设计可以类比画画的过程,首先通过 GLRenderTarget 这个类找到画布(封装了 WebGL 中的 framebuffer 概念),然后通过 GLTechnique 调好画笔,Technique 是 glTF 场景中引入的概念,包含了 Shader 程序的主要操作,最后通过 GLPrimitive 接受图元信息(VBO 和 IBO)执行 Drawcall 绘图指令 drawElementsdrawArrays

动画

引擎的最后部分讲一下动画,动画赋予整个 3D 场景灵魂。以去年“花呗双十一主会场”的动画为例,拿到这样的设计稿,很多前端同学会很崩溃,用传统的前端技术是无法实现的,觉得干脆就用视频来播放一下就满足需求了,但视频方案有几个问题:

  • 高清视频一般体积都比较大,对移动端来说用户无法接受,边下载边播放中间可能出现网络抖动造成卡住的现象;
  • 视频在安卓手机上存在无法自动播放的问题,iOS低电量模式也无法自动播放,目前没有好的解决方案;
  • 视频的可配置性和可交互性太差,比如无法根据业务需求产生不同的粒子动画效果。

而 Web 3D 方案不存在这些问题。在这个案例中,这个令人眼花缭乱的动画由骨骼动画、粒子动画、自定义Shader动画等组成,接下来详细讲一下骨骼动画和粒子动画的实现原理。

骨骼动画由 Maya、C4D 等专业 3D 美术软件制作,导出成 glTF 格式,其中包含了骨架与蒙皮信息。骨架由多个骨骼组成,通过 4x4 的矩阵来驱动每根骨骼的旋转等变换,骨架带动蒙皮,蒙皮通过不同的权重系数影响了顶点位置的变化,最后大家看到效果就是顶点位移后的效果。要注意的时候在移动端骨骼数是有限制的,超出之后部分骨骼动画将无法播放。

粒子动画 的实现重点在于把大量计算从 CPU 转移到 GPU 并行计算,CPU 通过每帧输入一个最简单的时间值给 GPU 来实现每个粒子的位置、旋转角度、透明度、贴图UV等数值的更新,它的算法很简单,就是中学物理中的匀变速运动。

小结

综上,从架构、渲染、动画三个维度,可以看到 Oasis 3D 引擎的特点:

  • 微内核架构,组件式扩展;
  • glTF2.0 及配套 PBR 材质支持;
  • 丰富多样的动画系统。

Oasis 3D 工作流

虽然有了一个能力相对完备的引擎,但是实际项目开发过程中我们仍然遇到诸多研发效率问题。以去年“借呗双十一预热游戏“为例,如果手写代码来实现,就会面临流程繁琐、上手成本高、反复联调等问题。我们可以通过高效的工作流来避免因这些问题造成的时间浪费,释放出更多的精力来打磨游戏和动画。

工作流的探索,我们也走过一些曲折的路。刚开始,我们希望借助 Unity 强大的能力来对接3D建模软件导出的美术资产,并且完成3D场景的搭建,然后通过 Unity 的 glTF Exproter 插件导出产物供 JS 运行时加载。这条路刚开始觉得很完美,但是真正使用的时候发现各种不尽人意的地方。比如在前端工程师中很少人熟悉 Unity,安装并学习这个软件就是门槛;Unity 中渲染的效果和在 Web 中不一致;通过插件导出的 glTF 需要手动优化并上传 CDN。另外,美术素材往往会不断迭代,每次通过 Unity 这个“中介”来调整场景和材质很耗时,反反复复,过程枯燥。现在基于 NPM、Babel、Webpack、React 等技术栈的前端开发环境已经很复杂了,这样的 3D 研发工作流更加消磨了做 3D 应用的信心。

为了解决工作流1.0的问题,我们迈向了工作流2.0。其中,最重要的部分是自研了一个开箱即用的在线编辑器 Oasis Editor。通过这个编辑器我们实现了美术资源的无缝对接,并且面向前端工程设计,让整个 3D 研发过程高效且富有创作感。

关于工作流2.0,我会从资产、编排、协作三个维度介绍。

资产

3D 美术资产如何快速进引擎?很简单,我们编写了一个云端资产标准化服务集成到编辑器中,上传 FBX 文件直接转成适合 Web 环境的 glTF 和 Webp 格式并发布到CDN,即使美术资产不断修改,迭代过程也高效轻松。以去年双十一“花呗金主帮还”项目为例,共有十个“花小呗”模型,临近项目发布,设计师只给了三个,最后补充的七个模型通过编辑器快速迭代,没有影响项目的最终上线。

解决美术资产的快速标准化问题之后,我们还考虑到了资产的沉淀与消费,目前正在建设蚂蚁 3D 资产市场,希望通过 Oasis Editor 这个资产调节管线,与市场打通,并且通过编辑器的“库”面板实现资产的下载复用。

编排

对 Oasis Editor 来说,编排包含两方面:一个是能力编排,一个是动画编排。

编辑器的能力编排是“引擎”章节中“能力扩展”的过程式代码的结构化展示,同样是写一个蚂蚁跳舞的动画效果,在编辑器中只要通过点击“添加能力”按钮完成各种能力的组合,避免了写大量样板式代码。

编辑器的动画编排是我们正在解决的问题。Oasis 3D 虽然具有丰富多样的动画系统,但是写个复杂的组合动画是个痛苦的过程,比如动画中的“等待”通过 setTimeout 来实现,动画代码的可维护性很差,也很难还原设计师想要的效果。为了解决“维护难”和“还原难”两个问题,我们开发了类似 AE 的 Timeline 编辑器,实现骨骼动画、插值动画、Shader 动画等片段的编排。

协作

有人可能会问:为什么 Oasis Editor 要做成一个在线编辑器?的确,现在用 Electron 等框架也可以快速地使用前端技术开发本地应用。在线编辑器的好处在于异地协同,比如设计师在北京,要调整一个模型的 PBR 材质,我在杭州只要发个 URL 地址给他就可以轻松完成材质的调整。

3D 场景开发完毕,项目并没有结束。一般现代前端项目都是 React 或 Vue 工程,如何把 3D 场景放到前端项目代码里,并且可以边编写业务逻辑边调整 3D 场景呢?我们使用 Web Socket 来实现 Oasis Editor 与 本地工程的双向同步,同时 IDE 也解决了Oasis 3D“扩展能力”的脚本编写。随着 Cloud IDE 的发展,我们未来会把前端开发转移到云上,这样就可以实现整个 3D 研发工作流的线上化。

小结

综上,从资产、编排、协作三个维度,可以看到 Oasis 3D 工作流的特点:

  • 资产云端标准化,打通资产市场;
  • 能力编排和动画编排可视化;
  • 与设计和前端开发顺畅协作。

未来展望

关于未来,Web 3D 技术可以想象的空间很大。引擎技术方面,我们会扩展更多高性能、高级渲染的特性,并且基于阿里经济体的应用场景布局互动游戏、工业产品、3D数据可视化三大业务引擎。

我们和蚂蚁的算法团队合作,通过视觉算法获取图片或视频中人物的动作,生成蚂蚁公仔的骨骼动画,从而解放设计生产力。

我们和达摩院人工智能实验室合作,通过手势来辅助 AR 场景的交互。我相信手机不会是人类获取信息的终态,未来人类重新抬起头的时候 AR 技术才真正开始大方光彩。

我们也正在和国内顶尖的 AR 眼镜设计制造商洽谈,为他们的合作伙伴提供 3D 内容工作流和 3D 渲染能力。

最后,简单介绍一下 Oasis 3D 的目标,大家可能比较关心的是开源时间;我们希望通过三年的努力跻身世界一流 3D 引擎,能够代表中国去参加世界顶级的图形会议。谢谢大家!

视频 && Slide

我的演讲视频和 PPT 都已经上传到:SEE Conf 的语雀专栏,欢迎下载,同时也欢迎到 知乎问答 跟我互动。

SEE Conf 是蚂蚁金服体验科技大会,是一个“看见者的大会”,希望技术能看见设计的价值,希望设计能看见技术的力量,彼此看见中互相融合成长,一起让世界更美好。
编辑于 2020-01-08

文章被以下专栏收录

    本专栏由蚂蚁金服消费信贷体验技术部(简称微贷)创办,微贷前端是一支年轻的前端团队,我们的使命是为金融世界带来很多微小但很美好的改变。 我们将与大家分享前端各领域的高质量技术文章,包括但不限于移动端、小程序、互动技术/数据可视化、Node.js 全栈/中后台、基础架构、个人思考,不限于原创与翻译。我们也欢迎优质文章的投稿。