从踩坑到填坑|淘宝Web 3D应用与游戏开发实战

导读:本文是淘宝前端技术专家——徐乾伟(烧鹅)分享的淘宝 Web 3D 应用与游戏开发实战,这个话题在业界被谈及得比较少。今天将会从移动、3D、游戏三种交叉的话题来和你们探讨。接下来和小编一块儿从初试 Web 3D、使用 WebGL、工做流相关的游戏编辑器三个部分来了解吧~

讲师介绍

徐乾伟(烧鹅)-淘宝前端技术专家,来自淘宝虚拟互动团队,这个团队主攻 3D /游戏/ VR / AR 。其中,咱们有一个小团队叫斜杠实验室,主攻 Web 方向上的动画和 3D 技术。前端

为何咱们会在这样交叉领域去发力作一些事情?去年的双十一淘宝去年交易额多少?一千多亿,其中有 80% 的 GMV 是来自移动端的,简单地理解就是说咱们公司在电商领域 80% 的钱是经过手机客户端赚取的,而不是 PC 。这就是为何在咱们要在移动端作 3D/VR/AR 的应用。web

初试Web 3D

有一句话叫:给我一个支点,我就能撬动地球。算法

不少人都作过 2D 游戏, 3D 最大的区别就是多了一根 Z 轴,而给我一个 Z 轴我就能创造 3D 世界。不少作前端的同窗对 3D 这个事情是有误解的,好比说 HTML5 中的 Canvas 有两个上下文,你们认为 2d Context 只能画 2D,WebGL context 才能画 3D ,这是一种误解。canvas

其实 3D 和 2D 并非由绘图引擎来决定的,而是由数学家决定的。假如咱们要画这样的曲面会怎么画呢?后端

首先有描述这个面的公式,这个公式根据 X、Y 入参算出 Z 的坐标值,假设 Z 越大颜色越红,Z 越小颜色越绿,画出来是这样的。若是 X、Y、Z 乘以一种神奇的东西叫矩阵(矩阵是数学家发明的),这是 3×3 的旋转矩阵,把每一个点都乘一下,而后画到屏幕上获得的结果就是这样的。设计模式

你们是否是一脸懵逼呀~浏览器

关于如何用 Canvas 2d 绘制 3D 曲面,之后再详细讲解,我有一段时间写过 CSS3D 的库,就是用 glMatrix 数学库作出很是酷炫的效果。网络

使用 Web GL

2016 年双十一咱们作过一个小游戏,不知道你们有没有玩过?架构

这个游戏是用 Canvas 2d 绘制,就是用的 glMatrix 数学库画实现 3D 效果。当时为何用 Canvas 2d 呢?咱们淘宝市场部的同窗说咱们要作 3D ,由于 pokemongo 作了一个 3D 的,可是你这个东西最后要给我搞到 iPhone 4 上去。你们知道 iPhone 4是不支持 WebGL 的,而当时开发时间很是紧张,我只能用 Canvas 2d 的方案。dom

若是点了主场景中的猫,就会进入一个 AR 捉猫的环境。这个不是 web 渲染,由于当时移动端的 web 还不具有获取摄像头数据的能力,因此当时 AR 只能用 Native 的 3D 引擎渲染,叫 T3D,顾名思义 Taobao 3D 。另外还有一个比较有趣的 AR 场景,叫“黄金猫”。黄金猫在双十一先后三天会出如今银泰或者苏宁的商场上方,你只要抢到了这只猫至少有一百块钱的红包奖励。

难点一:建筑模型的制做,咱们的设计师是个平面设计师,不会作 3D ,他当时给个人图是这样的,你看着办吧,我当时花了整整一天时间作模型。

难点二:地面算法,这个地面是六边型的结构,要把地面从地球坐标系转换成 3D 世界里的场景,会分几步。咱们小时候都看过世界地图,怎样把一个球形的面投射到平面上呢?

这种投影叫作墨卡托投影(Mercator projection)。这个投影算法的代码是服务端拷给个人,由于要保持先后端算法一致,我复制了后端的投影算法。相比墨卡托投影,这是简化的算法,由于要求看到周围的猫是在五十米左右,因此精度并非特别高,简单的算法就可以知足了。

当时的视角是这样的,以用户当前的位置经纬度为中心,辐射一圈就能够看到周围有多少只猫。

这里的六边型地面若是用 X、Y 两个轴的算法去计算实际上是比较慢的,我当时看了一篇论文,这是一个斯坦福的同窗花了二十年研究六边型的算法,他本质上是以夹角为 120 度的 X、Y、Z 三个轴为坐标轴算,相比算 X、Y 两个轴的算法快不少。上面还有不少基于这个基础算法拓展的算法如寻路等。

好不容易跨过了双十一的坎,咱们已经看到 Canvas 2d 的方案在模型输入和绘制性能方面都是很是弱的。
如何继续开发 3D 类的游戏呢?可能你们会问,WebGL 在 PC 上都不行,在手机上行不行呀?我跟你们说,如今彻底没问题,咱们在上亿台同时在线的设备上都试过了,前提是要作一下 WebGL 能力检测。 PC 还有一些古董浏览器不支持 WebGL ,反而手机比 PC 发展快得太多。

你们以前理解了 3D 的概念, 3D 不是绘图引擎的功能, 3D 是数学的概念。那 CPU 绘图与 GPU 绘图有什么区别呢?GPU 是并行处理每个像素的。

咱们刚开始尝试 WebGL 当心翼翼,由于怕给手淘带来影响,事实上也形成比较大的 Crash 。

2016 年的圣诞节,市场部同窗说要不在手淘里下一场雪吧,那就下了。后面我会和你们介绍下这场雪的代价。咱们还尝试作相似于右边这种模型粒子动画,这是一只天猫的模型。这两个都是粒子系统,由于咱们刚开始不知道怎么作复杂的 3D 渲染,咱们只能从最基础的绘制“点”出发去尝试。

咱们团队有一种叫 PopLayer 的技术,能够在当前 Native View 上面随时弹出一层 Web View。好比以前搜一下鹿晗出弹幕,还有明星打电话,都是经过 PopLayer 技术实现的。

上文提到,在淘宝首页的 Poplayer 里 下一场雪致使了大面积的客户端Crash 。缘由是 iOS 下的 UIWebView 使用 webgl 渲染时,WebCore 会调用到 OpenGL ES 进行渲染,而苹果发现有在后台调用 OpenGL ES,就会直接结束 App。

知道 RequestAnimationFrame API 吗?解法就是监测当前用户退出后台或当前页面不可见时,会把 RequestAnimationFrame 中止。

小倩也提到过 Page Visibility 方面的 API ,咱们发现安卓是支持这个 API 的, 但 IOS 仍是须要调 Js Bridge接口来监听 App 的是否退后台的状态。接着,我把游戏主循环(或者动画主循环)停下来以后还发现一些用户会 Crash 。最后我发现一件很是神奇的事情~这个代码你们都知道,它是用来获取Canvas的WebGL context,这行代码为何Crash呢?咱们翻了 Webkit 的源码发现它有一个 reshape 函数,reshape 会经过 GPU 获取当前画布的高宽,因此它仍是会 Crash 。

接下来将会分享 3D 之旅咱们的心情,以及个人思惟是如何进化的。

2017 年的造物节时咱们作了真正意义上的 3D 应用,当时跟英国一家设计公司合做叫 FRAMESTORE ,这个电影(《奇异博士》)你们知道吧,特效就是他们设计制做的。

FRAMESTORE 当时给个人东西是这样的,俯视图是这样的,灯光是这样打的。虽然他们在影视特效领域很是牛逼,可是他们也没作过 Web 应用。而我当时也不知道怎么和设计团队合做,仍是个人老方法手写代码。他们给个人模型,我当时也不知道其余高级的格式,只知道 Obj + Mtl 。若是发现 WebGL 渲染有问题,咱们就去代码里找缘由,模型引用的材质对不对,贴图对不对。咱们要翻代码看一下是否是引用错了。工做流的问题在这个项目中没有解决,可是促使我开始寻找问题的解法。

这个项目还有一个性能问题,广告牌发光效果,我第一个想到的是后处理(Post Processing),你们不理解的话,能够把它看成实时滤镜,若是在手机屏幕这么大的 Bloom 滤镜是会卡死的。我当时的方案是在每块广告牌上写一个独立的 Shader ,这样在iphone6上至少是能够流畅渲染的。

游戏编辑器

上面讲了这么多,痛苦和迷茫。其实我以前作的东西也不能称之为真正的游戏,只能算是营销互动类游戏。

咱们仍是以为作游戏要向业界规范的方案靠拢,因此 游戏编辑器是必需要作的。虽然我今天并无作出一款游戏编辑器,我会跟你们分享为何我要作游戏编辑器(如今已经正在作了),这中间的坎坷是今天要讲的重点。

和英国团队合做以后我很是难过,他们的设计作得那么酷,而我只能实现成这样。我在中国环顾一圈,没有看到 Web 3D 游戏方面比较好的方案,由于在中国作 WebGL 的都百里挑一。

2017 年我去澳洲参加了 Web 3D 大会,他们当时用了 X3dom 像 HTML 同样用标签地描述 3D 世界。
这是一种很是陈旧的技术,虽然也是基于 WebGL 渲染。这个方案已经推了十几年了,老外也不知道为何这么执着,有几十个 Paper 都是讲这个的。他们讲的东西都很是学术,我以为对咱们的帮助并非很大。

而后我又去工业界寻找解决方案。这是前索尼 PlayStation 的一位同窗作的应用,他用的技术你们可能会大吃一惊,他用了Unity。第一次看到 Unity 和 Web 嫁接起来是很是令我震惊的。我当时用的是 iphone6 ,运行这个 demo 都是 60 fps 满帧,他是怎么作到的呢?我去查了一下它的代码,虽然代码是压缩过的,可是为了突破这个技术难关,我阅读了压缩后的代码而且理解了它背后的实现。

我发现里面有各类各样的新颖的技术。好比,Unity 能够合并 3D 模型的贴图。

合并贴图这件事情是很重要的。作前端的同窗都知道雪碧图,为何作雪碧图?你们都知道是为了减小网络请求数,可是其实合并贴图对运行时的性能有很大影响。 
GPU 读一张图快仍是读十张图快?计算机资源是很是宝贵的,图片要适度合并尽可能压缩。一张 200K 的图片,可能占用 3-4 倍的显存。 JS 优化半年减小 30K ,图片批量压缩减小个几兆都是有可能的,因此要把时间花在可以快速见效的事情上面。

下图的 Texture Baker 就是用来烘培而且合并图片。这个是 ITween Path 是 Unity 作路径动画的插件。
Unity还有一个插件叫 Collada Exporter 。Collada 是标准的 3D 模型格式,看到这里咱们已经抛弃了以前 Obj+Mtl 的老方案。而Runtime根据我以前的开发经验封装了一套 MVC 的方案。

基于这套工做流,咱们作了 2017 年双十一切红包项目。咱们常常调侃:腾讯作游戏和阿里作有戏有什么区别?腾讯作游戏是收钱,咱们作游戏是发钱。用 Unity 带来的好处是可以直接导入设计师给的源文件,如 Maya 源文件、 Photoshop 源文件。这里咱们看到,红包模型是预先切开的,你们知道切水果也是这样作的,即便你竖着切菠萝它仍是横着裂开的。

至于红包的特效,我会常常逛一些国外的网站,这是某个游戏开发者写的 Shader 特效,我就照着他的思路来写了一个相似的。

你们看到一个红包在天上飞,上面有光在流动,其实整个场景中一盏灯都没有打。光照计算,特别是点光源的计算是很是耗性能的。因此你们作 3D 应用的时候尽可能要少放光源。这种效果其实只要在像素着色器中写一行代码就解决了。

红包是怎么切中的呢?Picking 这个话题对没有开发过游戏的人也许比较陌生,切红包的游戏里我当时作了两种方案:一种叫作 CPU Picker ,另外一种是 GPU Picker 。

CPU Picker:在每一个红包上面套上一个包围盒,计算射线有没有击中这个包围盒,由于 CPU Picker 的计算成本和场景的复杂度正相关, 用包围盒会比较快;

GPU Picker:经过拾取离屏画布上面的颜色值就好了。

虽然感受 GPU Picker 性能会特别好,但在移动端性能表现却不佳,由于拾取颜色的过程其实是 CPU 和 GPU 通讯的过程,这个过程会比较慢。因此,CPU Picker 性能会更好一点。

还有一点就是 Dom 操做,在 Web 游戏开发中,Dom 操做就是魔鬼。我抓了比较慢的一帧花了 25 毫秒(约 40 帧)。

游戏逻辑加上 Web GL 渲染就花了那么几毫秒,而 DOM 操做却耗掉很长的时间,并且还引起了重绘(紫色部分)。

因此 Dom在游戏里是不合适的,GUI 部分须要用 2D 的 Canvas 或者 Web GL 渲染去解决。

最后讲一下音效,我我的很是喜欢游戏中声音给我带来的奖励。我作切红包的时候注意到了上面几点,这也是我上周去北京 Unity 大会上听到关于 CRIWare 的声音中间件的内容:

  • 背景音乐要有渐有渐出,这样用户体验比较好;
  • 用户作一些操做或者比较重要操做的时候,当前声音要强调一下,背景音乐减弱一下;
  • 声音要有变化,好比说不少射击的游戏,若是枪声都同样,用户听觉会疲劳的,咱们切红包时左切和右切都是不同的。

这个软件叫 bfxr,是一款制做游戏音效的小软件,在线和客户端版本都有,人人均可以设计音效。

讲了那么多技术点,咱们总要看一下业界真正作游戏的人是怎么作的。我大概探索了一两年,发现 Playcanvas 引擎是 Web 世界上最健全的游戏引擎。它的引擎代码是开源的,可是编辑器不开源。我分析了一下它的引擎源码,大概有几部分组成:

  • ECS 的架构,Unity 也是采用这样的设计模式。
  • PBR,基于物理的渲染模型,看起来更像真实世界的渲染。物理引擎也是很重要的,还有输入设备,好比说你的游戏手柄、手机都是输入设备。

Playcanvas 和 Threejs 有什么区别?

Threejs 只是一个 3D 渲染库。游戏还有一个很是重要的东西叫编辑器,这是 Playcanvas 在线的编辑器,我看了这个游戏以后就以为必定要作编辑器,由于编辑器是引擎的载体。若是没有编辑器,咱们每次开发游戏要注意的工程和技术问题太多。

编辑器架构

最后讲一下咱们团队思考的编辑器的架构,如今只是一张工程架构图。

游戏最后发布的内容是什么?就是一堆资源,图片、模型、音频、脚本,在 Web 开发环境中最后都要发上 CDN 。

游戏里的大部分资源如音频、全景图、模型这些都是第三方软件输入的,模型资源的序列化、减面、合并、烘培等操做咱们暂时可能不会去作(仍是交给 Unity 作),中间 GUI 部分就是编辑器的面板操做,最后 Script 组件和 Shader 能够经过 Vscode 来编辑。这张图是我一两年的心得,你们能够留言区交流~



本文做者:徐乾伟(烧鹅) 

阅读原文

本文为云栖社区原创内容,未经容许不得转载。

相关文章
相关标签/搜索