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

640?wx_fmt=jpeg

作者|徐乾伟(烧鹅) 

出品|阿里巴巴新零售淘系技术部


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

扫描下方二维码,关注「淘宝技术」,回复“游戏”即可获得此次演讲 PPT 。

640?wx_fmt=jpeg


讲师介绍

640?wx_fmt=jpeg

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

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


初试Web 3D


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

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

640?wx_fmt=jpeg

其实 3D 和 2D 并不是由绘图引擎来决定的,而是由数学家决定的。 假如我们要画这样的曲面会怎么画呢?
首先有描述这个面的公式,这个公式根据 X、Y 入参算出 Z 的坐标值,假设 Z 越大颜色越红,Z 越小颜色越绿,画出来是这样的。 如果 X、Y、Z 乘以一种神奇的东西叫矩阵(矩阵是数学家发明的),这是 3×3 的旋转矩阵,把每个点都乘一下,然后画到屏幕上得到的结果就是这样的。
大家是不是一脸懵逼呀~u1F602.png
关于如何用 Canvas 2d  绘制 3D 曲面,以后再详细讲解, 我有一段时间写过 CSS3D 的库,就是用 glMatrix  数学库做出非常酷炫的效果。

使用 Web GL

640?wx_fmt=jpeg

2016 年双十一我们做过一个小游戏,不知道大家有没有玩过?
这个游戏是用 Canvas 2d 绘制,就是用的 glMatrix 数学库画实现 3D 效果。 当时为什么用 Canvas 2d 呢? 我们淘宝市场部的同学说我们要做 3D ,因为 pokemongo 做了一个 3D 的,但是你这个东西最后要给我搞到 iPhone 4 上去。 大家知道 iPhone 4是不支持 WebGL 的,而当时开发时间非常紧张,我只能用 Canvas 2d 的方案。
如果点了主场景中的猫,就会进入一个 AR 捉猫的环境。 这个不是 web 渲染,因为当时移动端的 web 还不具备获取摄像头数据的能力, 所以当时 AR 只能用 Native 的 3D 引擎渲染,叫 T3D,顾名思义 Taobao 3D 。 另外还有一个比较有趣的 AR 场景,叫“黄金猫”。 黄金猫在双十一前后三天会出现在银泰或者苏宁的商场上方,你只要抢到了这只猫至少有一百块钱的红包奖励。
难点一:建筑模型的制作 , 我们的设计师是个平面设计师,不会做 3D ,他当时给我的图是这样的,你看着办吧,我当时花了整整一天时间做模型。
难点二:地面算法, 这个 地面是六边型的结构,要把地面从地球坐标系转换成 3D 世界里的场景,会分几步。我们小时候都看过世界地图,怎样把一个球形的面投射到平面上呢?
这种投影叫做墨卡托投影Mercator projection)。这个投影算法的代码是服务端拷给我的,因为要保持前后端算法一致,我复制了后端的投影算法。相比墨卡托投影,这是简化的算法,因为要求看到周围的猫是在五十米左右,所以精度并不是特别高,简单的算法就能够满足了。

640?wx_fmt=jpeg

当时的视角是这样的,以用户当前的位置经纬度为中心,辐射一圈就可以看到周围有多少只猫。
这里的六边型地面如果用 X、Y 两个轴的算法去计算其实是比较慢的,我当时看了一篇论文,这是一个斯坦福的同学花了二十年研究六边型的算法,他本质上是以夹角为 120 度的 X、Y、Z 三个轴为坐标轴算,相比算 X、Y 两个轴的算法快很多。 上面还有很多基于这个基础算法拓展的算法如寻路等。
好不容易跨过了双十一的坎,我们已经看到 Canvas 2d 的方案在模型输入和绘制性能方面都是非常弱的。
如何继续开发 3D 类的游戏呢? 可能大家会问,WebGL 在 PC 上都不行,在手机上行不行呀? 我跟大家说,现在完全没问题,我们在上亿台同时在线的设备上都试过了,前提是要做一下 WebGL 能力检测。  PC 还有一些古董浏览器不支持 WebGL ,反而手机比 PC 发展快得太多。

640?wx_fmt=jpeg

大家之前理解了 3D 的概念, 3D 不是绘图引擎的功能, 3D 是数学的概念。 那 CPU 绘图与 GPU 绘图有什么区别呢? GPU 是并行处理每一个像素的。
我们刚开始尝试 WebGL 小心翼翼,因为怕给手淘带来影响,事实上也造成比较大的 Crash 。
2016 年的圣诞节,市场部同学说要不在手淘里下一场雪吧,那就下了。 后面我会和大家介绍下这场雪的代价。 我们还尝试做类似于右边这种模型粒子动画,这是一只天猫的模型。 这两个都是粒子系统,因为我们刚开始不知道怎么做复杂的 3D 渲染,我们只能从最基础的绘制“点”出发去尝试。

640?wx_fmt=jpeg

我们团队有一种叫 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 。 最后我发现一件非常神奇的事情~这个代码大家都知道,它是用来获取CanvasWebGL context,这行代码为什么Crash呢? 我们翻了 Webkit 的源码发现它有一个 reshape 函数,reshape 会通过 GPU 获取当前画布的高宽,所以它还是会 Crash 。
接下来将会分享 3D 之旅我们的心情,以及我的思维是如何进化的。
2017 年的造物节时我们做了真正意义上的 3D 应用,当时跟英国一家设计公司合作叫 FRAMESTORE ,这个电影(《奇异博士》)大家知道吧,特效就是他们设计制作的。

640?wx_fmt=jpeg

FRAMESTORE 当时给我的东西是这样的,俯视图是这样的,灯光是这样打的。 虽然他们在影视特效领域非常牛逼,但是他们也没做过 Web 应用。 而我当时也不知道怎么和设计团队合作,还是我的老方法手写代码。 他们给我的模型,我当时也不知道其他高级的格式,只知道 Obj + Mtl 。 如果发现 WebGL 渲染有问题,我们就去代码里找原因,模型引用的材质对不对,贴图对不对。 我们要翻代码看一下是不是引用错了。 工作流的问题在这个项目中没有解决,但是促使我开始寻找问题的解法。
这个项目还有一个性能问题,广告牌发光效果,我第一个想到的是后处理(Post Processing),大家不理解的话,可以把它当作实时滤镜,如果在手机屏幕这么大的 Bloom 滤镜是会卡死的。 我当时的方案是在每块广告牌上写一个独立的 Shader ,这样在iphone6上至少是可以流畅渲染的。

游戏编辑器

上面讲了这么多,痛苦和迷茫。 其实我之前做的东西也不能称之为真正的游戏,只能算是营销互动类游戏。
我们还是觉得做游戏要向业界规范的方案靠拢,所以 游戏编辑器是必须要做的。 虽然我今天并没有做出一款游戏编辑器,我会跟大家分享为什么我要做游戏编辑器(现在已经正在做了),这中间的坎坷是今天要讲的重点。

640?wx_fmt=jpeg

和英国团队合作之后我非常难过,他们的设计做得那么酷,而我只能实现成这样。 我在中国环顾一圈,没有看到 Web 3D 游戏方面比较好的方案,因为在中国做 WebGL 的都凤毛麟角。
2017 年我去澳洲参加了 Web 3D 大会,他们当时用了 X3dom 像 HTML 一样用标签地描述 3D 世界。
这是一种非常陈旧的技术,虽然也是基于 WebGL 渲染。 这个方案已经推了十几年了,老外也不知道为什么这么执着,有几十个 Paper 都是讲这个的。 他们讲的东西都非常学术,我觉得对我们的帮助并不是很大。
然后我又去工业界寻找解决方案。 这是前索尼 PlayStation 的一位同学做的应用,他用的技术大家可能会大吃一惊,他用了Unity。 第一次看到 Unity 和 Web 嫁接起来是非常令我震惊的。 我当时用的是 iphone6 ,运行这个 demo 都是 60 fps 满帧,他是怎么做到的呢? 我去查了一下它的代码,虽然代码是压缩过的,但是为了突破这个技术难关,我阅读了压缩后的代码并且理解了它背后的实现。

640?wx_fmt=jpeg

我发现里面有各种各样的新颖的技术。 比如,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 源文件。 这里我们看到,红包模型是预先切开的,大家知道切水果也是这样做的,即使你竖着切菠萝它还是横着裂开的。

640?wx_fmt=jpeg

至于红包的特效,我会经常逛一些国外的网站,这是某个游戏开发者写的 Shader 特效,我就照着他的思路来写了一个类似的。
大家看到一个红包在天上飞,上面有光在流动,其实整个场景中一盏灯都没有打。 光照计算,特别是点光源的计算是非常耗性能的。 所以大家做 3D 应用的时候尽量要少放光源。 这种效果其实只要在像素着色器中写一行代码就解决了。
红包是怎么切中的呢? Picking 这个话题对没有开发过游戏的人也许比较陌生,切红包的游戏里我当时做了两种方案: 一种叫做 CPU Picker ,另一种是 GPU Picker 
CPU Picker: 在每个红包上面套上一个包围盒,计算射线有没有击中这个包围盒,因为 CPU Picker 的计算成本和场景的复杂度正相关, 用包围盒会比较快;
GPU Picker: 通过拾取离屏画布上面的颜色值就行了。
虽然感觉 GPU Picker 性能会特别好,但在移动端性能表现却不佳,因为拾取颜色的过程实际上是 CPU 和 GPU 通信的过程,这个过程会比较慢。 所以,CPU Picker  性能会更好一点。

640?wx_fmt=jpeg

还有一点就是 Dom 操作,在 Web 游戏开发中,Dom 操作就是魔鬼。 我抓了比较慢的一帧花了 25 毫秒(约 40 帧)。
游戏逻辑加上 Web GL 渲染就花了那么几毫秒,而 DOM 操作却耗掉很长的时间,而且还引发了重绘(紫色部分)。
所以 Dom在游戏里是不合适的,GUI 部分需要用 2D 的 Canvas 或者 Web GL 渲染去解决。

640?wx_fmt=jpeg

最后讲一下音效,我个人非常喜欢游戏中声音给我带来的奖励。 我做切红包的时候注意到了上面几点,这也是我上周去北京 Unity 大会上听到关于 CRIWare 的声音中间件的内容:
  • 背景音乐要有渐有渐出,这样用户体验比较好;

  • 用户做一些操作或者比较重要操作的时候,当前声音要强调一下,背景音乐减弱一下;

  • 声音要有变化,比如说很多射击的游戏,如果枪声都一样,用户听觉会疲劳的,我们切红包时左切和右切都是不一样的。

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

640?wx_fmt=jpeg

讲了那么多技术点,我们总要看一下业界真正做游戏的人是怎么做的。 我大概探索了一两年,发现 Playcanvas 引擎是 Web 世界上最健全的游戏引擎。 它的引擎代码是开源的,但是编辑器不开源。 我分析了一下它的引擎源码,大概有几部分组成: 
  • ECS 的架构,Unity 也是采用这样的设计模式。

  • PBR,基于物理的渲染模型,看起来更像真实世界的渲染。物理引擎也是很重要的,还有输入设备,比如说你的游戏手柄、手机都是输入设备。

Playcanvas 和 Threejs 有什么区别?
Threejs 只是一个 3D 渲染库。 游戏还有一个非常重要的东西叫编辑器,这是 Playcanvas 在线的编辑器,我看了这个游戏之后就觉得一定要做编辑器,因为编辑器是引擎的载体。 如果没有编辑器,我们每次开发游戏要注意的工程和技术问题太多。

编辑器架构

最后讲一下我们团队思考的编辑器的架构,现在只是一张工程架构图。
游戏最后发布的内容是什么?就是一堆资源,图片、模型、音频、脚本,在 Web 开发环境中最后都要发上 CDN 。
游戏里的大部分资源如音频、全景图、模型这些都是第三方软件输入的,模型资源的序列化、减面、合并、烘培等操作我们暂时可能不会去做(还是交给 Unity 做),中间 GUI 部分就是编辑器的面板操作,最后 Script 组件和 Shader 可以通过 Vscode 来编辑。这张图是我一两年的心得,大家可以留言区交流~

640?wx_fmt=jpeg

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值