
导读前端
FDCON2018中国前端开发者千人峰会上,来自淘宝技术虚拟互动团队的烧鹅在现场分享了淘宝Web 3D应用和游戏开发的实战。首先详细解释了3D与2D的区别,并阐述了在有限的环境下,淘宝技术虚拟互动团队是如何经过Canvas去实现3D效果。随着Web GL的发展,如何在手机淘宝中实践,以及在项目中如何与Unity结合提高开发效率。而如今,团队但愿可以实现一个可视化的编辑器,帮助开发者快速得构建出相关的应用。web
你们下午好!咱们今天讲个比较有意思的话题,这个话题在业界被谈及得比较少。你们在座有作过移动端开发的同窗吗?请举个手,人还挺多的。那作过3D应用的同窗请举个手,有用过Threejs的请举个手,作过游戏的呢..人这么少,那我就放心了,能够大胆讲了(全场笑) 。今天讲的正是移动、3D、游戏三者交叉的话题。算法
canvas
自我介绍一下,我来自淘宝虚拟互动团队,这个团队主攻3D/游戏/VR/AR。其中,咱们有一个小团队叫斜杠实验室(</Lab>),主攻Web方向上的动画和3D技术。为何咱们会在这样交叉领域去发力作一些事情?去年的双十一淘宝去年交易额多少?一千多亿,其中有80%的GMV是来自移动端的,简单地理解就是说咱们公司在电商领域80%的成交是经过手机客户端实现的,而不是PC。这就是为何在咱们要在移动端作3D/VR/AR的应用。后端
我今天演讲分为三块内容:设计模式
第一部分讲述初试Web 3D浏览器
第二部分讲使用 WebGL 微信
第三部分讲工做流相关的游戏编辑器网络
有一句话叫:给我一个支点,我就能撬动地球。不少人都作过2D游戏,3D最大的区别就是多了一根Z轴,而给我一个Z轴我就能创造3D世界。不少作前端的同窗对3D这个事情是有误解的,好比说 HTML5中的 Canvas 有两个上下文,你们认为 2d Context 只能画2D,WebGL context 才能画3D,这是一种误解。架构
其实3D和2D并非由绘图引擎来决定的,而是由数学家决定的。假如咱们要画这样的曲面会怎么画呢?首先有描述这个面的公式,这个公式根据X、Y入参算出Z的坐标值,假设Z越大颜色越红,Z越小颜色越绿,画出来是这样的。若是X、Y、Z乘以一种神奇的东西叫矩阵(矩阵是数学家发明的),这是3×3的旋转矩阵,把每一个点都乘一下,而后画到屏幕上获得的结果就是这样的。你们是否是一脸懵逼呀?这里有一篇MSDN的文章专门讲解了如何用 Canvas 2d 绘制3D曲面。我有一段时间写过CSS3D的库,就是用 glMatrix 数学库作出很是酷炫的效果。
2016年双十一咱们作过一个小游戏,这个游戏有玩过的吗?(观众举手)。这个游戏是用Canvas 2d 绘制,就是用的 glMatrix 数学库画实现3D效果。当时为何用Canvas 2d 呢?咱们淘宝市场部的同窗说咱们要作3D,由于人家 pokemongo 作了一个3D的,可是你这个东西最后要给我搞到 iPhone 4上去。你们知道 iPhone 4是不支持WebGL的,而当时开发时间很是紧张,我只能用了 Canvas 2d 的方案。
若是点了主场景中的猫,就会进入一个AR捉猫的环境。这个不是web渲染,由于当时移动端的web还不具有获取摄像头数据的能力,个人一个同事正在另一个分会场讲WebRTC,你们后面有兴趣能够听一下。因此当时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绘图有什么区别呢?你们看一个小电影,这是英伟达几个工程师录的视频,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年我去澳洲参加了Web3D大会,他们当时用了 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,经过拾取离屏画布上面的颜色值就好了。虽然感受GPUPicker性能会特别好,但在移动端性能表现却不佳,由于拾取颜色的过程其实是CPU和GPU通讯的过程,这个过程会比较慢。因此,CPU Picker 性能会更好一点。
还有一点就是Dom操做,在Web游戏开发中,Dom操做就是魔鬼。我抓了比较慢的一帧花了25毫秒(约40帧)。游戏逻辑加上WebGL渲染就花了那么几毫秒,而DOM操做却耗掉很长的时间,并且还引起了重绘(紫色部分)。因此 Dom 在游戏里是不合适的,GUI 部分须要用2D的Canvas或者WebGL渲染去解决。
最后讲一下音效,我我的很是喜欢游戏中声音给我带来的奖励。我作切红包的时候注意到了上面几点,这也是我上周去北京Unity大会上听到关于CRIWare的声音中间件的内容:
1. 背景音乐要有渐有渐出,这样用户体验比较好;
2.用户作一些操做或者比较重要操做的时候,当前声音要强调一下,背景音乐减弱一下;
3.声音要有变化,好比说不少射击的游戏,若是枪声都同样,用户听觉会疲劳的,咱们切红包时左切和右切都是不同的。
这个软件叫 bfxr,是一款制做游戏音效的小软件,在线和客户端版本都有,人人均可以设计音效。
讲了那么多技术点,咱们总要看一下业界真正作游戏的人是怎么作的。我大概探索了一两年,发现 Playcanvas 引擎是Web世界上最健全的游戏引擎。它的引擎代码是开源的,可是编辑器不开源。我分析了一下它的引擎源码,大概有几部分组成:ECS的架构,Unity 也是采用这样的设计模式。第二个是PBR,基于物理的渲染模型,看起来更像真实世界的渲染。物理引擎也是很重要的,还有输入设备,好比说你的游戏手柄、手机都是输入设备。Playcanvas 和 Threejs 有什么区别?Threejs只是一个3D渲染库。游戏还有一个很是重要的东西叫编辑器,这是 Playcanvas在线的编辑器,我看了这个游戏以后就以为必定要作编辑器,由于编辑器是引擎的载体。若是没有编辑器,咱们每次开发游戏要注意的工程和技术问题太多。
最后讲一下咱们团队思考的编辑器的架构,如今只是一张工程架构图。游戏最后发布的内容是什么?就是一堆资源,图片、模型、音频、脚本,在Web开发环境中最后都要发上CDN。游戏里的大部分资源如音频、全景图、模型这些都是第三方软件输入的,模型资源的序列化、减面、合并、烘培等操做咱们暂时可能不会去作(仍是交给Unity作),中间GUI部分就是编辑器的面板操做,最后 Script 组件和 Shader 能够经过 VS Code 来编辑。这张图是我一两年的心得,里面有一些细节时间问题这里就不展开了。OK,我讲完了,你们有什么问题。
问1:开发游戏是否是要先学习数学知识?
烧鹅:这些都是骗人的,游戏引擎都封装了数学库。游戏开发中,边作边学很重要。我举个我上周在Unity Beijing听到的例子,开发青蛙旅行的人在他们公司是个助理工程师,一群前辈都把活给都扔给了他,而后他就开发出来了。关于游戏和图形的数学方面的书,你只要搜一下游戏数学的关键词,就会出来很是多的结果。
问2:老师您好,咱们这边咱们的团队都是Web开发的,对游戏开发不是很清楚,以现有的Web开发为基础,咱们的同窗应该学习那些知识?
烧鹅:前端转型到游戏开发者,能够先试着作一款游戏,或者说别人作了一款比较好玩的游戏,你不看源代码的状况下,你用本身具有的技术知识克隆出来,你在作的过程当中天然而然会接触到游戏开发中的各类概念和知识体系。
本文分享自微信公众号 - 淘系技术(AlibabaMTT)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。